package elliptic
import (
)
var p224 p224Curve
type p224Curve struct {
*CurveParams
gx, gy, b p224FieldElement
}
func () {
p224.CurveParams = &CurveParams{Name: "P-224"}
p224.P, _ = new(big.Int).SetString("26959946667150639794667015087019630673557916260026308143510066298881", 10)
p224.N, _ = new(big.Int).SetString("26959946667150639794667015087019625940457807714424391721682722368061", 10)
p224.B, _ = new(big.Int).SetString("b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4", 16)
p224.Gx, _ = new(big.Int).SetString("b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21", 16)
p224.Gy, _ = new(big.Int).SetString("bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", 16)
p224.BitSize = 224
p224FromBig(&p224.gx, p224.Gx)
p224FromBig(&p224.gy, p224.Gy)
p224FromBig(&p224.b, p224.B)
}
func () Curve {
initonce.Do(initAll)
return p224
}
func ( p224Curve) () *CurveParams {
return .CurveParams
}
func ( p224Curve) (, *big.Int) bool {
var , p224FieldElement
p224FromBig(&, )
p224FromBig(&, )
var p224LargeFieldElement
var p224FieldElement
p224Square(&, &, &)
p224Mul(&, &, &, &)
for := 0; < 8; ++ {
[] *= 3
}
p224Sub(&, &, &)
p224Reduce(&)
p224Add(&, &, &.b)
p224Contract(&, &)
p224Square(&, &, &)
p224Contract(&, &)
for := 0; < 8; ++ {
if [] != [] {
return false
}
}
return true
}
func (p224Curve) (, , , *big.Int) (, *big.Int) {
var , , , , , , , , p224FieldElement
p224FromBig(&, )
p224FromBig(&, )
if .Sign() != 0 || .Sign() != 0 {
[0] = 1
}
p224FromBig(&, )
p224FromBig(&, )
if .Sign() != 0 || .Sign() != 0 {
[0] = 1
}
p224AddJacobian(&, &, &, &, &, &, &, &, &)
return p224ToAffine(&, &, &)
}
func (p224Curve) (, *big.Int) (, *big.Int) {
var , , , , , p224FieldElement
p224FromBig(&, )
p224FromBig(&, )
[0] = 1
p224DoubleJacobian(&, &, &, &, &, &)
return p224ToAffine(&, &, &)
}
func (p224Curve) (, *big.Int, []byte) (, *big.Int) {
var , , , , , p224FieldElement
p224FromBig(&, )
p224FromBig(&, )
[0] = 1
p224ScalarMult(&, &, &, &, &, &, )
return p224ToAffine(&, &, &)
}
func ( p224Curve) ( []byte) (, *big.Int) {
var , , , p224FieldElement
[0] = 1
p224ScalarMult(&, &, &, &.gx, &.gy, &, )
return p224ToAffine(&, &, &)
}
type p224FieldElement [8]uint32
var p224P = [8]uint32{1, 0, 0, 0xffff000, 0xfffffff, 0xfffffff, 0xfffffff, 0xfffffff}
func ( *p224FieldElement) uint32 {
var p224FieldElement
p224Contract(&, )
var , uint32
for , := range {
|=
|= - p224P[]
}
|= >> 16
|= >> 8
|= >> 4
|= >> 2
|= >> 1
|= >> 16
|= >> 8
|= >> 4
|= >> 2
|= >> 1
:= &
= (^) & 1
return
}
func (, , *p224FieldElement) {
for := 0; < 8; ++ {
[] = [] + []
}
}
const two31p3 = 1<<31 + 1<<3
const two31m3 = 1<<31 - 1<<3
const two31m15m3 = 1<<31 - 1<<15 - 1<<3
var p224ZeroModP31 = []uint32{two31p3, two31m3, two31m3, two31m15m3, two31m3, two31m3, two31m3, two31m3}
func (, , *p224FieldElement) {
for := 0; < 8; ++ {
[] = [] + p224ZeroModP31[] - []
}
}
type p224LargeFieldElement [15]uint64
const two63p35 = 1<<63 + 1<<35
const two63m35 = 1<<63 - 1<<35
const two63m35m19 = 1<<63 - 1<<35 - 1<<19
var p224ZeroModP63 = [8]uint64{two63p35, two63m35, two63m35, two63m35, two63m35m19, two63m35, two63m35, two63m35}
const bottom12Bits = 0xfff
const bottom28Bits = 0xfffffff
func (, , *p224FieldElement, *p224LargeFieldElement) {
for := 0; < 15; ++ {
[] = 0
}
for := 0; < 8; ++ {
for := 0; < 8; ++ {
[+] += uint64([]) * uint64([])
}
}
p224ReduceLarge(, )
}
func (, *p224FieldElement, *p224LargeFieldElement) {
for := 0; < 15; ++ {
[] = 0
}
for := 0; < 8; ++ {
for := 0; <= ; ++ {
:= uint64([]) * uint64([])
if == {
[+] +=
} else {
[+] += << 1
}
}
}
p224ReduceLarge(, )
}
func ( *p224FieldElement, *p224LargeFieldElement) {
for := 0; < 8; ++ {
[] += p224ZeroModP63[]
}
for := 14; >= 8; -- {
[-8] -= []
[-5] += ([] & 0xffff) << 12
[-4] += [] >> 16
}
[8] = 0
for := 1; < 8; ++ {
[+1] += [] >> 28
[] = uint32([] & bottom28Bits)
}
[0] -= [8]
[3] += uint32([8]&0xffff) << 12
[4] += uint32([8] >> 16)
[0] = uint32([0] & bottom28Bits)
[1] += uint32(([0] >> 28) & bottom28Bits)
[2] += uint32([0] >> 56)
}
func ( *p224FieldElement) {
for := 0; < 7; ++ {
[+1] += [] >> 28
[] &= bottom28Bits
}
:= [7] >> 28
[7] &= bottom28Bits
:=
|= >> 2
|= >> 1
<<= 31
= uint32(int32() >> 31)
[0] -=
[3] += << 12
[3] -= 1 &
[2] += & (1<<28 - 1)
[1] += & (1<<28 - 1)
[0] += & (1 << 28)
}
func (, *p224FieldElement) {
var , , , p224FieldElement
var p224LargeFieldElement
p224Square(&, , &)
p224Mul(&, &, , &)
p224Square(&, &, &)
p224Mul(&, &, , &)
p224Square(&, &, &)
p224Square(&, &, &)
p224Square(&, &, &)
p224Mul(&, &, &, &)
p224Square(&, &, &)
for := 0; < 5; ++ {
p224Square(&, &, &)
}
p224Mul(&, &, &, &)
p224Square(&, &, &)
for := 0; < 11; ++ {
p224Square(&, &, &)
}
p224Mul(&, &, &, &)
p224Square(&, &, &)
for := 0; < 23; ++ {
p224Square(&, &, &)
}
p224Mul(&, &, &, &)
p224Square(&, &, &)
for := 0; < 47; ++ {
p224Square(&, &, &)
}
p224Mul(&, &, &, &)
p224Square(&, &, &)
for := 0; < 23; ++ {
p224Square(&, &, &)
}
p224Mul(&, &, &, &)
for := 0; < 6; ++ {
p224Square(&, &, &)
}
p224Mul(&, &, &, &)
p224Square(&, &, &)
p224Mul(&, &, , &)
for := 0; < 97; ++ {
p224Square(&, &, &)
}
p224Mul(, &, &, &)
}
func (, *p224FieldElement) {
copy([:], [:])
for := 0; < 7; ++ {
[+1] += [] >> 28
[] &= bottom28Bits
}
:= [7] >> 28
[7] &= bottom28Bits
[0] -=
[3] += << 12
for := 0; < 3; ++ {
:= uint32(int32([]) >> 31)
[] += (1 << 28) &
[+1] -= 1 &
}
for := 3; < 7; ++ {
[+1] += [] >> 28
[] &= bottom28Bits
}
= [7] >> 28
[7] &= bottom28Bits
[0] -=
[3] += << 12
for := 0; < 3; ++ {
:= uint32(int32([]) >> 31)
[] += (1 << 28) &
[+1] -= 1 &
}
:= uint32(0xffffffff)
for := 4; < 8; ++ {
&= []
}
|= 0xf0000000
&= >> 16
&= >> 8
&= >> 4
&= >> 2
&= >> 1
= uint32(int32(<<31) >> 31)
:= [0] | [1] | [2]
|= >> 16
|= >> 8
|= >> 4
|= >> 2
|= >> 1
= uint32(int32(<<31) >> 31)
:= 0xffff000 - [3]
:=
|= >> 16
|= >> 8
|= >> 4
|= >> 2
|= >> 1
= ^uint32(int32(<<31) >> 31)
:= uint32(int32() >> 31)
:= & (( & ) | )
[0] -= 1 &
[3] -= 0xffff000 &
[4] -= 0xfffffff &
[5] -= 0xfffffff &
[6] -= 0xfffffff &
[7] -= 0xfffffff &
for := 0; < 3; ++ {
:= uint32(int32([]) >> 31)
[] += (1 << 28) &
[+1] -= 1 &
}
}
func (, , , , , , , , *p224FieldElement) {
var , , , , , , , , , , p224FieldElement
var p224LargeFieldElement
:= p224IsZero()
:= p224IsZero()
p224Square(&, , &)
p224Square(&, , &)
p224Mul(&, , &, &)
p224Mul(&, , &, &)
p224Mul(&, , &, &)
p224Mul(&, , &, &)
p224Mul(&, , &, &)
p224Mul(&, , &, &)
p224Sub(&, &, &)
p224Reduce(&)
:= p224IsZero(&)
for := 0; < 8; ++ {
[] = [] << 1
}
p224Reduce(&)
p224Square(&, &, &)
p224Mul(&, &, &, &)
p224Sub(&, &, &)
p224Reduce(&)
:= p224IsZero(&)
if == 1 && == 1 && == 0 && == 0 {
p224DoubleJacobian(, , , , , )
return
}
for := 0; < 8; ++ {
[] <<= 1
}
p224Reduce(&)
p224Mul(&, &, &, &)
p224Add(&, &, &)
p224Add(&, , )
p224Reduce(&)
p224Square(&, &, &)
p224Sub(, &, &)
p224Reduce()
p224Mul(, , &, &)
for := 0; < 8; ++ {
[] = [] << 1
}
p224Add(&, &, &)
p224Reduce(&)
p224Square(, &, &)
p224Sub(, , &)
p224Reduce()
for := 0; < 8; ++ {
[] <<= 1
}
p224Mul(&, &, &, &)
p224Sub(&, &, )
p224Reduce(&)
p224Mul(&, &, &, &)
p224Sub(, &, &)
p224Reduce()
p224CopyConditional(, , )
p224CopyConditional(, , )
p224CopyConditional(, , )
p224CopyConditional(, , )
p224CopyConditional(, , )
p224CopyConditional(, , )
}
func (, , , , , *p224FieldElement) {
var , , , , p224FieldElement
var p224LargeFieldElement
p224Square(&, , &)
p224Square(&, , &)
p224Mul(&, , &, &)
p224Add(&, , &)
for := 0; < 8; ++ {
[] += [] << 1
}
p224Reduce(&)
p224Sub(&, , &)
p224Reduce(&)
p224Mul(&, &, &, &)
p224Add(, , )
p224Reduce()
p224Square(, , &)
p224Sub(, , &)
p224Reduce()
p224Sub(, , &)
p224Reduce()
for := 0; < 8; ++ {
[] = [] << 3
}
p224Reduce(&)
p224Square(, &, &)
p224Sub(, , &)
p224Reduce()
for := 0; < 8; ++ {
[] <<= 2
}
p224Sub(&, &, )
p224Reduce(&)
p224Square(&, &, &)
for := 0; < 8; ++ {
[] <<= 3
}
p224Reduce(&)
p224Mul(, &, &, &)
p224Sub(, , &)
p224Reduce()
}
func (, *p224FieldElement, uint32) {
<<= 31
= uint32(int32() >> 31)
for := 0; < 8; ++ {
[] ^= ([] ^ []) &
}
}
func (, , , , , *p224FieldElement, []byte) {
var , , p224FieldElement
for := 0; < 8; ++ {
[] = 0
[] = 0
[] = 0
}
for , := range {
for := uint(0); < 8; ++ {
p224DoubleJacobian(, , , , , )
:= uint32(( >> (7 - )) & 1)
p224AddJacobian(&, &, &, , , , , , )
p224CopyConditional(, &, )
p224CopyConditional(, &, )
p224CopyConditional(, &, )
}
}
}
func (, , *p224FieldElement) (*big.Int, *big.Int) {
var , , , p224FieldElement
var p224LargeFieldElement
if := p224IsZero(); == 1 {
return new(big.Int), new(big.Int)
}
p224Invert(&, )
p224Square(&, &, &)
p224Mul(, , &, &)
p224Mul(&, &, &, &)
p224Mul(, , &, &)
p224Contract(&, )
p224Contract(&, )
return p224ToBig(&), p224ToBig(&)
}
func ( []byte, uint) (uint32, []byte) {
var uint32
for := uint(0); < 4; ++ {
var byte
if := len(); > 0 {
= [-1]
if != 3 || == 4 {
= [:-1]
}
}
|= uint32() << (8 * ) >>
}
&= bottom28Bits
return ,
}
func ( *p224FieldElement, *big.Int) {
:= .Bytes()
[0], = get28BitsFromEnd(, 0)
[1], = get28BitsFromEnd(, 4)
[2], = get28BitsFromEnd(, 0)
[3], = get28BitsFromEnd(, 4)
[4], = get28BitsFromEnd(, 0)
[5], = get28BitsFromEnd(, 4)
[6], = get28BitsFromEnd(, 0)
[7], = get28BitsFromEnd(, 4)
}
func ( *p224FieldElement) *big.Int {
var [28]byte
[27] = byte([0])
[26] = byte([0] >> 8)
[25] = byte([0] >> 16)
[24] = byte((([0] >> 24) & 0x0f) | ([1]<<4)&0xf0)
[23] = byte([1] >> 4)
[22] = byte([1] >> 12)
[21] = byte([1] >> 20)
[20] = byte([2])
[19] = byte([2] >> 8)
[18] = byte([2] >> 16)
[17] = byte((([2] >> 24) & 0x0f) | ([3]<<4)&0xf0)
[16] = byte([3] >> 4)
[15] = byte([3] >> 12)
[14] = byte([3] >> 20)
[13] = byte([4])
[12] = byte([4] >> 8)
[11] = byte([4] >> 16)
[10] = byte((([4] >> 24) & 0x0f) | ([5]<<4)&0xf0)
[9] = byte([5] >> 4)
[8] = byte([5] >> 12)
[7] = byte([5] >> 20)
[6] = byte([6])
[5] = byte([6] >> 8)
[4] = byte([6] >> 16)
[3] = byte((([6] >> 24) & 0x0f) | ([7]<<4)&0xf0)
[2] = byte([7] >> 4)
[1] = byte([7] >> 12)
[0] = byte([7] >> 20)
return new(big.Int).SetBytes([:])
}