1
0
mirror of https://github.com/henrydcase/nobs.git synced 2024-11-22 15:18:57 +00:00

Improves some comments and hardcodes precomputed value (#4)

* Improves some comments and hardcodes precomputed value

* Tests curve coefficients recovery
This commit is contained in:
Henry Case 2018-08-07 12:05:52 +01:00 committed by Kris Kwiatkowski
parent 51688dc4bb
commit b769c88767
2 changed files with 80 additions and 17 deletions

View File

@ -11,8 +11,8 @@ type ProjectiveCurveParameters struct {
// Stores curve projective parameters equivalent to A/C. Meaning of the // Stores curve projective parameters equivalent to A/C. Meaning of the
// values depends on the context. When working with isogenies over // values depends on the context. When working with isogenies over
// subgroup that are powers of: // subgroup that are powers of:
// * three then A=(A+2C)/4; C=(A-2C)/4 // * three then (A:C) ~ (A+2C:A-2C)
// * four then A=(A+2C)/4; C=4C // * four then (A:C) ~ (A+2C: 4C)
// See Appendix A of SIKE for more details // See Appendix A of SIKE for more details
type CurveCoefficientsEquiv struct { type CurveCoefficientsEquiv struct {
A ExtensionFieldElement A ExtensionFieldElement
@ -93,26 +93,25 @@ func (curve *ProjectiveCurveParameters) RecoverCoordinateA(xp, xq, xr *Extension
// Computes equivalence (A:C) ~ (A+2C : A-2C) // Computes equivalence (A:C) ~ (A+2C : A-2C)
func (curve *ProjectiveCurveParameters) CalcCurveParamsEquiv3() CurveCoefficientsEquiv { func (curve *ProjectiveCurveParameters) CalcCurveParamsEquiv3() CurveCoefficientsEquiv {
var coef CurveCoefficientsEquiv var coef CurveCoefficientsEquiv
var tmp ExtensionFieldElement var c2 ExtensionFieldElement
// TODO: Calling code sets C=1, always (all functions). Currently only tests // TODO: Calling code sets C=1, always (all functions). Currently only tests
// require C to be customizable. // require C to be customizable.
// C24 = 2*C c2.Add(&curve.C, &curve.C)
tmp.Add(&curve.C, &curve.C) // A24p = A+2*C
// A24_plus = A + 2C coef.A.Add(&curve.A, &c2)
coef.A.Add(&curve.A, &tmp) // A24m = A-2*C
// A24_minus = A - 2C coef.C.Sub(&curve.A, &c2)
coef.C.Sub(&curve.A, &tmp)
return coef return coef
} }
// Computes equivalence (A:C) ~ (A+2C : 2C) // Computes equivalence (A:C) ~ (A+2C : 4C)
func (cparams *ProjectiveCurveParameters) CalcCurveParamsEquiv4() CurveCoefficientsEquiv { func (cparams *ProjectiveCurveParameters) CalcCurveParamsEquiv4() CurveCoefficientsEquiv {
var coefEq CurveCoefficientsEquiv var coefEq CurveCoefficientsEquiv
// C = 2*cparams.C
coefEq.C.Add(&cparams.C, &cparams.C) coefEq.C.Add(&cparams.C, &cparams.C)
// A24_plus = A + 2C // A24p = A + 2C
coefEq.A.Add(&cparams.A, &coefEq.C) coefEq.A.Add(&cparams.A, &coefEq.C)
// C24 = 4*C // C24 = 4*C
coefEq.C.Add(&coefEq.C, &coefEq.C) coefEq.C.Add(&coefEq.C, &coefEq.C)
@ -136,18 +135,31 @@ func (cparams *ProjectiveCurveParameters) calcAplus2Over4() (ret ExtensionFieldE
// Recovers (A:C) curve parameters from projectively equivalent (A+2C:A-2C). // Recovers (A:C) curve parameters from projectively equivalent (A+2C:A-2C).
func (cparams *ProjectiveCurveParameters) RecoverCurveCoefficients3(coefEq *CurveCoefficientsEquiv) { func (cparams *ProjectiveCurveParameters) RecoverCurveCoefficients3(coefEq *CurveCoefficientsEquiv) {
cparams.A.Add(&coefEq.A, &coefEq.C) cparams.A.Add(&coefEq.A, &coefEq.C)
// cparams.A = 2*(A+2C+A-2C) = 4A
cparams.A.Add(&cparams.A, &cparams.A) cparams.A.Add(&cparams.A, &cparams.A)
// cparams.C = (A+2C-A+2C) = 4C
cparams.C.Sub(&coefEq.A, &coefEq.C) cparams.C.Sub(&coefEq.A, &coefEq.C)
return return
} }
// Recovers (A:C) curve parameters from projectively equivalent (A+2C:2C). // Recovers (A:C) curve parameters from projectively equivalent (A+2C:4C).
func (cparams *ProjectiveCurveParameters) RecoverCurveCoefficients4(coefEq *CurveCoefficientsEquiv) { func (cparams *ProjectiveCurveParameters) RecoverCurveCoefficients4(coefEq *CurveCoefficientsEquiv) {
var tmp ExtensionFieldElement // Represents 1/2 in montgomery form
tmp.Add(&oneExtensionField, &oneExtensionField).Inv(&tmp) var half = ExtensionFieldElement{
cparams.C.Mul(&coefEq.C, &tmp) A: Fp751Element{
0x00000000000124D6, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0xB8E0000000000000,
0x9C8A2434C0AA7287, 0xA206996CA9A378A3, 0x6876280D41A41B52,
0xE903B49F175CE04F, 0x0F8511860666D227, 0x00004EA07CFF6E7F},
B: Fp751Element{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
}
// cparams.C = (4C)*1/2=2C
cparams.C.Mul(&coefEq.C, &half)
// cparams.A = A+2C - 2C = A
cparams.A.Sub(&coefEq.A, &cparams.C) cparams.A.Sub(&coefEq.A, &cparams.C)
cparams.C.Mul(&cparams.C, &tmp) // cparams.C = 2C * 1/2 = C
cparams.C.Mul(&cparams.C, &half)
return return
} }

View File

@ -93,6 +93,8 @@ var threePointLadderInputs = []ProjectivePoint{
}, },
} }
// Helpers
func (P ProjectivePoint) Generate(rand *rand.Rand, size int) reflect.Value { func (P ProjectivePoint) Generate(rand *rand.Rand, size int) reflect.Value {
f := ExtensionFieldElement{} f := ExtensionFieldElement{}
x, _ := f.Generate(rand, size).Interface().(ExtensionFieldElement) x, _ := f.Generate(rand, size).Interface().(ExtensionFieldElement)
@ -113,6 +115,25 @@ func (curve ProjectiveCurveParameters) Generate(rand *rand.Rand, size int) refle
}) })
} }
// Sets FP(p^2) from uint64. x sets ExtensionsFieldElement.A (real part) and y
// ExtensionFieldElement.B (imaginary part).
//
// Returns dest to allow chaining operations.
func (dest *ExtensionFieldElement) SetUint64(x, y uint64) *ExtensionFieldElement {
var xRR fp751X2
dest.A = Fp751Element{} // = 0
dest.A[0] = x // = x
fp751Mul(&xRR, &dest.A, &montgomeryRsq) // = x*R*R
fp751MontgomeryReduce(&dest.A, &xRR) // = x*R mod p
dest.B = Fp751Element{} // = 0
dest.B[0] = y // = y
fp751Mul(&xRR, &dest.B, &montgomeryRsq) // = y*R*R
fp751MontgomeryReduce(&dest.B, &xRR) // = y*R mod p
return dest
}
// Helpers // Helpers
// Given xP = x(P), xQ = x(Q), and xPmQ = x(P-Q), compute xR = x(P+Q). // Given xP = x(P), xQ = x(Q), and xPmQ = x(P-Q), compute xR = x(P+Q).
@ -355,6 +376,36 @@ func TestPointTripleVersusAddDouble(t *testing.T) {
} }
} }
func TestProjectiveParamsRecovery(t *testing.T) {
var crv1, crv2 ProjectiveCurveParameters
var A4, C4, four ExtensionFieldElement
four.SetUint64(4, 0)
eqivParams3 := curve.CalcCurveParamsEquiv3()
eqivParams4 := curve.CalcCurveParamsEquiv4()
// This returns 4*A and 4*C
crv1.RecoverCurveCoefficients3(&eqivParams3)
crv2.RecoverCurveCoefficients4(&eqivParams4)
A4.Mul(&curve_A, &four)
C4.Mul(&curve_C, &four)
if !crv1.A.VartimeEq(&A4) {
t.Error("\nExpected\n", crv1.A, "\nfound\n", A4)
}
if !crv1.C.VartimeEq(&C4) {
t.Error("\nExpected\n", crv1.C, "\nfound\n", C4)
}
if !crv2.A.VartimeEq(&curve_A) {
t.Error("\nExpected\n", crv2.A, "\nfound\n", curve_A)
}
if !crv2.C.VartimeEq(&curve_C) {
t.Error("\nExpected\n", crv2.C, "\nfound\n", curve_C)
}
}
func BenchmarkThreePointLadder379BitScalar(b *testing.B) { func BenchmarkThreePointLadder379BitScalar(b *testing.B) {
var mScalarBytes = [...]uint8{84, 222, 146, 63, 85, 18, 173, 162, 167, 38, 10, 8, 143, 176, 93, 228, 247, 128, 50, 128, 205, 42, 15, 137, 119, 67, 43, 3, 61, 91, 237, 24, 235, 12, 53, 96, 186, 164, 232, 223, 197, 224, 64, 109, 137, 63, 246, 4} var mScalarBytes = [...]uint8{84, 222, 146, 63, 85, 18, 173, 162, 167, 38, 10, 8, 143, 176, 93, 228, 247, 128, 50, 128, 205, 42, 15, 137, 119, 67, 43, 3, 61, 91, 237, 24, 235, 12, 53, 96, 186, 164, 232, 223, 197, 224, 64, 109, 137, 63, 246, 4}