package nistec
import (
)
var p224B, _ = new(fiat.P224Element).SetBytes([]byte{0xb4, 0x05, 0x0a, 0x85,
0x0c, 0x04, 0xb3, 0xab, 0xf5, 0x41, 0x32, 0x56, 0x50, 0x44, 0xb0, 0xb7,
0xd7, 0xbf, 0xd8, 0xba, 0x27, 0x0b, 0x39, 0x43, 0x23, 0x55, 0xff, 0xb4})
var p224G, _ = NewP224Point().SetBytes([]byte{0x04,
0xb7, 0x0e, 0x0c, 0xbd, 0x6b, 0xb4, 0xbf, 0x7f, 0x32, 0x13, 0x90, 0xb9,
0x4a, 0x03, 0xc1, 0xd3, 0x56, 0xc2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xd6,
0x11, 0x5c, 0x1d, 0x21, 0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb,
0x4c, 0x22, 0xdf, 0xe6, 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64,
0x44, 0xd5, 0x81, 0x99, 0x85, 0x0, 0x7e, 0x34})
const p224ElementLength = 28
type P224Point struct {
x, y, z *fiat.P224Element
}
func () *P224Point {
return &P224Point{
x: new(fiat.P224Element),
y: new(fiat.P224Element).One(),
z: new(fiat.P224Element),
}
}
func () *P224Point {
return (&P224Point{
x: new(fiat.P224Element),
y: new(fiat.P224Element),
z: new(fiat.P224Element),
}).Set(p224G)
}
func ( *P224Point) ( *P224Point) *P224Point {
.x.Set(.x)
.y.Set(.y)
.z.Set(.z)
return
}
func ( *P224Point) ( []byte) (*P224Point, error) {
switch {
case len() == 1 && [0] == 0:
return .Set(NewP224Point()), nil
case len() == 1+2*p224ElementLength && [0] == 4:
, := new(fiat.P224Element).SetBytes([1 : 1+p224ElementLength])
if != nil {
return nil,
}
, := new(fiat.P224Element).SetBytes([1+p224ElementLength:])
if != nil {
return nil,
}
if := p224CheckOnCurve(, ); != nil {
return nil,
}
.x.Set()
.y.Set()
.z.One()
return , nil
case len() == 1+p224ElementLength && [0] == 0:
return nil, errors.New("unimplemented")
default:
return nil, errors.New("invalid P224 point encoding")
}
}
func (, *fiat.P224Element) error {
:= new(fiat.P224Element).Square()
.Mul(, )
:= new(fiat.P224Element).Add(, )
.Add(, )
.Sub(, )
.Add(, p224B)
:= new(fiat.P224Element).Square()
if .Equal() != 1 {
return errors.New("P224 point not on curve")
}
return nil
}
func ( *P224Point) () []byte {
var [133]byte
return .bytes(&)
}
func ( *P224Point) ( *[133]byte) []byte {
if .z.IsZero() == 1 {
return append([:0], 0)
}
:= new(fiat.P224Element).Invert(.z)
:= new(fiat.P224Element).Mul(.x, )
:= new(fiat.P224Element).Mul(.y, )
:= append([:0], 4)
= append(, .Bytes()...)
= append(, .Bytes()...)
return
}
func ( *P224Point) (, *P224Point) *P224Point {
:= new(fiat.P224Element).Mul(.x, .x)
:= new(fiat.P224Element).Mul(.y, .y)
:= new(fiat.P224Element).Mul(.z, .z)
:= new(fiat.P224Element).Add(.x, .y)
:= new(fiat.P224Element).Add(.x, .y)
.Mul(, )
.Add(, )
.Sub(, )
.Add(.y, .z)
:= new(fiat.P224Element).Add(.y, .z)
.Mul(, )
.Add(, )
.Sub(, )
.Add(.x, .z)
:= new(fiat.P224Element).Add(.x, .z)
.Mul(, )
.Add(, )
.Sub(, )
:= new(fiat.P224Element).Mul(p224B, )
.Sub(, )
.Add(, )
.Add(, )
.Sub(, )
.Add(, )
.Mul(p224B, )
.Add(, )
.Add(, )
.Sub(, )
.Sub(, )
.Add(, )
.Add(, )
.Add(, )
.Add(, )
.Sub(, )
.Mul(, )
.Mul(, )
.Mul(, )
.Add(, )
.Mul(, )
.Sub(, )
.Mul(, )
.Mul(, )
.Add(, )
.x.Set()
.y.Set()
.z.Set()
return
}
func ( *P224Point) ( *P224Point) *P224Point {
:= new(fiat.P224Element).Square(.x)
:= new(fiat.P224Element).Square(.y)
:= new(fiat.P224Element).Square(.z)
:= new(fiat.P224Element).Mul(.x, .y)
.Add(, )
:= new(fiat.P224Element).Mul(.x, .z)
.Add(, )
:= new(fiat.P224Element).Mul(p224B, )
.Sub(, )
:= new(fiat.P224Element).Add(, )
.Add(, )
.Sub(, )
.Add(, )
.Mul(, )
.Mul(, )
.Add(, )
.Add(, )
.Mul(p224B, )
.Sub(, )
.Sub(, )
.Add(, )
.Add(, )
.Add(, )
.Add(, )
.Sub(, )
.Mul(, )
.Add(, )
.Mul(.y, .z)
.Add(, )
.Mul(, )
.Sub(, )
.Mul(, )
.Add(, )
.Add(, )
.x.Set()
.y.Set()
.z.Set()
return
}
func ( *P224Point) (, *P224Point, int) *P224Point {
.x.Select(.x, .x, )
.y.Select(.y, .y, )
.z.Select(.z, .z, )
return
}
func ( *P224Point) ( *P224Point, []byte) *P224Point {
var = [16]*P224Point{
NewP224Point(), NewP224Point(), NewP224Point(), NewP224Point(),
NewP224Point(), NewP224Point(), NewP224Point(), NewP224Point(),
NewP224Point(), NewP224Point(), NewP224Point(), NewP224Point(),
NewP224Point(), NewP224Point(), NewP224Point(), NewP224Point(),
}
for := 1; < 16; ++ {
[].Add([-1], )
}
:= NewP224Point()
.Set(NewP224Point())
for , := range {
.Double()
.Double()
.Double()
.Double()
for := uint8(0); < 16; ++ {
:= subtle.ConstantTimeByteEq(>>4, )
.Select([], , )
}
.Add(, )
.Double()
.Double()
.Double()
.Double()
for := uint8(0); < 16; ++ {
:= subtle.ConstantTimeByteEq(&0b1111, )
.Select([], , )
}
.Add(, )
}
return
}