main
1package brainpool
2
3import (
4 "crypto/elliptic"
5 "math/big"
6)
7
8var _ elliptic.Curve = (*rcurve)(nil)
9
10type rcurve struct {
11 twisted elliptic.Curve
12 params *elliptic.CurveParams
13 z *big.Int
14 zinv *big.Int
15 z2 *big.Int
16 z3 *big.Int
17 zinv2 *big.Int
18 zinv3 *big.Int
19}
20
21var (
22 two = big.NewInt(2)
23 three = big.NewInt(3)
24)
25
26func newrcurve(twisted elliptic.Curve, params *elliptic.CurveParams, z *big.Int) *rcurve {
27 zinv := new(big.Int).ModInverse(z, params.P)
28 return &rcurve{
29 twisted: twisted,
30 params: params,
31 z: z,
32 zinv: zinv,
33 z2: new(big.Int).Exp(z, two, params.P),
34 z3: new(big.Int).Exp(z, three, params.P),
35 zinv2: new(big.Int).Exp(zinv, two, params.P),
36 zinv3: new(big.Int).Exp(zinv, three, params.P),
37 }
38}
39
40func (curve *rcurve) toTwisted(x, y *big.Int) (*big.Int, *big.Int) {
41 var tx, ty big.Int
42 tx.Mul(x, curve.z2)
43 tx.Mod(&tx, curve.params.P)
44 ty.Mul(y, curve.z3)
45 ty.Mod(&ty, curve.params.P)
46 return &tx, &ty
47}
48
49func (curve *rcurve) fromTwisted(tx, ty *big.Int) (*big.Int, *big.Int) {
50 var x, y big.Int
51 x.Mul(tx, curve.zinv2)
52 x.Mod(&x, curve.params.P)
53 y.Mul(ty, curve.zinv3)
54 y.Mod(&y, curve.params.P)
55 return &x, &y
56}
57
58func (curve *rcurve) Params() *elliptic.CurveParams {
59 return curve.params
60}
61
62func (curve *rcurve) IsOnCurve(x, y *big.Int) bool {
63 return curve.twisted.IsOnCurve(curve.toTwisted(x, y))
64}
65
66func (curve *rcurve) Add(x1, y1, x2, y2 *big.Int) (x, y *big.Int) {
67 tx1, ty1 := curve.toTwisted(x1, y1)
68 tx2, ty2 := curve.toTwisted(x2, y2)
69 return curve.fromTwisted(curve.twisted.Add(tx1, ty1, tx2, ty2))
70}
71
72func (curve *rcurve) Double(x1, y1 *big.Int) (x, y *big.Int) {
73 return curve.fromTwisted(curve.twisted.Double(curve.toTwisted(x1, y1)))
74}
75
76func (curve *rcurve) ScalarMult(x1, y1 *big.Int, scalar []byte) (x, y *big.Int) {
77 tx1, ty1 := curve.toTwisted(x1, y1)
78 return curve.fromTwisted(curve.twisted.ScalarMult(tx1, ty1, scalar))
79}
80
81func (curve *rcurve) ScalarBaseMult(scalar []byte) (x, y *big.Int) {
82 return curve.fromTwisted(curve.twisted.ScalarBaseMult(scalar))
83}