Pārlūkot izejas kodu

cln16sidh: add de/serialization for SIDH public keys

trials/prep_p503_trial3
Henry de Valence pirms 7 gadiem
vecāks
revīzija
11976a638e
3 mainītis faili ar 140 papildinājumiem un 0 dzēšanām
  1. +68
    -0
      field.go
  2. +32
    -0
      field_test.go
  3. +40
    -0
      sidh.go

+ 68
- 0
field.go Parādīt failu

@@ -227,6 +227,28 @@ func (lhs *ExtensionFieldElement) VartimeEq(rhs *ExtensionFieldElement) bool {
return lhs.a.vartimeEq(rhs.a) && lhs.b.vartimeEq(rhs.b)
}

// Convert the input to wire format.
//
// The output byte slice must be at least 188 bytes long.
func (x *ExtensionFieldElement) ToBytes(output []byte) {
if len(output) < 188 {
panic("output byte slice too short, need 188 bytes")
}
x.a.toBytesFromMontgomeryForm(output[0:94])
x.b.toBytesFromMontgomeryForm(output[94:188])
}

// Read 188 bytes into the given ExtensionFieldElement.
//
// It is an error to call this function if the input byte slice is less than 188 bytes long.
func (x *ExtensionFieldElement) FromBytes(input []byte) {
if len(input) < 188 {
panic("input byte slice too short, need 188 bytes")
}
x.a.montgomeryFormFromBytes(input[:94])
x.b.montgomeryFormFromBytes(input[94:188])
}

//------------------------------------------------------------------------------
// Prime Field
//------------------------------------------------------------------------------
@@ -528,3 +550,49 @@ func (x fp751Element) vartimeEq(y fp751Element) bool {

return eq
}

// Read an fp751Element from little-endian bytes and convert to Montgomery form.
//
// The input byte slice must be at least 94 bytes long.
func (x *fp751Element) montgomeryFormFromBytes(input []byte) {
if len(input) < 94 {
panic("input byte slice too short")
}

var a fp751Element
for i := 0; i < 94; i++ {
// set i = j*8 + k
j := i / 8
k := uint64(i % 8)
a[j] |= uint64(input[i]) << (8 * k)
}

var aRR fp751X2
fp751Mul(&aRR, &a, &montgomeryRsq) // = a*R*R
fp751MontgomeryReduce(x, &aRR) // = a*R mod p
}

// Given an fp751Element in Montgomery form, convert to little-endian bytes.
//
// The output byte slice must be at least 94 bytes long.
func (x *fp751Element) toBytesFromMontgomeryForm(output []byte) {
if len(output) < 94 {
panic("output byte slice too short")
}

var a fp751Element
var aR fp751X2
copy(aR[:], x[:]) // = a*R
fp751MontgomeryReduce(&a, &aR) // = a mod p in [0, 2p)
fp751StrongReduce(&a) // = a mod p in [0, p)

// 8*12 = 96, but we drop the last two bytes since p is 751 < 752=94*8 bits.
for i := 0; i < 94; i++ {
// set i = j*8 + k
j := i / 8
k := uint64(i % 8)
// Need parens because Go's operator precedence would interpret
// a[j] >> 8*k as (a[j] >> 8) * k
output[i] = byte(a[j] >> (8 * k))
}
}

+ 32
- 0
field_test.go Parādīt failu

@@ -115,6 +115,38 @@ func (x ExtensionFieldElement) Generate(rand *rand.Rand, size int) reflect.Value
// Extension Field
//------------------------------------------------------------------------------

func TestOneExtensionFieldToBytes(t *testing.T) {
var x ExtensionFieldElement
var xBytes [188]byte

x.One()
x.ToBytes(xBytes[:])

if xBytes[0] != 1 {
t.Error("Expected 1, got", xBytes[0])
}
for i := 1; i < 188; i++ {
if xBytes[i] != 0 {
t.Error("Expected 0, got", xBytes[0])
}
}
}

func TestExtensionFieldElementToBytesRoundTrip(t *testing.T) {
roundTrips := func(x ExtensionFieldElement) bool {
var xBytes [188]byte
var xPrime ExtensionFieldElement
x.ToBytes(xBytes[:])
xPrime.FromBytes(xBytes[:])

return x.VartimeEq(&xPrime)
}

if err := quick.Check(roundTrips, quickCheckConfig); err != nil {
t.Error(err)
}
}

func TestExtensionFieldElementMulDistributesOverAdd(t *testing.T) {
mulDistributesOverAdd := func(x, y, z ExtensionFieldElement) bool {
// Compute t1 = (x+y)*z


+ 40
- 0
sidh.go Parādīt failu

@@ -50,12 +50,52 @@ type SIDHPublicKeyBob struct {
affine_xQmP ExtensionFieldElement
}

// Read a public key from a byte slice. The input must be at least 564 bytes long.
func (pubKey *SIDHPublicKeyBob) FromBytes(input []byte) {
if len(input) < 564 {
panic("Too short input to SIDH pubkey FromBytes, expected 564 bytes")
}
pubKey.affine_xP.FromBytes(input[0:188])
pubKey.affine_xQ.FromBytes(input[188:376])
pubKey.affine_xQmP.FromBytes(input[376:564])
}

// Write a public key to a byte slice. The output must be at least 564 bytes long.
func (pubKey *SIDHPublicKeyBob) ToBytes(output []byte) {
if len(output) < 564 {
panic("Too short output for SIDH pubkey FromBytes, expected 564 bytes")
}
pubKey.affine_xP.ToBytes(output[0:188])
pubKey.affine_xQ.ToBytes(output[188:376])
pubKey.affine_xQmP.ToBytes(output[376:564])
}

type SIDHPublicKeyAlice struct {
affine_xP ExtensionFieldElement
affine_xQ ExtensionFieldElement
affine_xQmP ExtensionFieldElement
}

// Read a public key from a byte slice. The input must be at least 564 bytes long.
func (pubKey *SIDHPublicKeyAlice) FromBytes(input []byte) {
if len(input) < 564 {
panic("Too short input to SIDH pubkey FromBytes, expected 564 bytes")
}
pubKey.affine_xP.FromBytes(input[0:188])
pubKey.affine_xQ.FromBytes(input[188:376])
pubKey.affine_xQmP.FromBytes(input[376:564])
}

// Write a public key to a byte slice. The output must be at least 564 bytes long.
func (pubKey *SIDHPublicKeyAlice) ToBytes(output []byte) {
if len(output) < 564 {
panic("Too short output for SIDH pubkey FromBytes, expected 564 bytes")
}
pubKey.affine_xP.ToBytes(output[0:188])
pubKey.affine_xQ.ToBytes(output[188:376])
pubKey.affine_xQmP.ToBytes(output[376:564])
}

type SIDHSecretKeyBob struct {
scalar []uint8
}


Notiek ielāde…
Atcelt
Saglabāt