OSDN Git Service

new repo
[bytom/vapor.git] / crypto / ed25519 / ecmath / scalar.go
1 package ecmath
2
3 import (
4         "crypto/subtle"
5
6         "github.com/vapor/crypto/ed25519/internal/edwards25519"
7 )
8
9 // Scalar is a 256-bit little-endian scalar.
10 type Scalar [32]byte
11
12 var (
13         // Zero is the number 0.
14         Zero Scalar
15
16         // One is the number 1.
17         One = Scalar{1}
18
19         // NegOne is the number -1 mod L
20         NegOne = Scalar{
21                 0xec, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
22                 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
23                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
24                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
25         }
26
27         // L is the subgroup order:
28         // 2^252 + 27742317777372353535851937790883648493
29         L = Scalar{
30                 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
31                 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
32                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
34         }
35 )
36
37 // Add computes x+y (mod L) and places the result in z, returning
38 // that. Any or all of x, y, and z may be the same pointer.
39 func (z *Scalar) Add(x, y *Scalar) *Scalar {
40         return z.MulAdd(x, &One, y)
41 }
42
43 // Sub computes x-y (mod L) and places the result in z, returning
44 // that. Any or all of x, y, and z may be the same pointer.
45 func (z *Scalar) Sub(x, y *Scalar) *Scalar {
46         return z.MulAdd(y, &NegOne, x)
47 }
48
49 // Neg negates x (mod L) and places the result in z, returning that. X
50 // and z may be the same pointer.
51 func (z *Scalar) Neg(x *Scalar) *Scalar {
52         return z.MulAdd(x, &NegOne, &Zero)
53 }
54
55 // MulAdd computes ab+c (mod L) and places the result in z, returning
56 // that. Any or all of the pointers may be the same.
57 func (z *Scalar) MulAdd(a, b, c *Scalar) *Scalar {
58         edwards25519.ScMulAdd((*[32]byte)(z), (*[32]byte)(a), (*[32]byte)(b), (*[32]byte)(c))
59         return z
60 }
61
62 func (z *Scalar) Equal(x *Scalar) bool {
63         return subtle.ConstantTimeCompare(x[:], z[:]) == 1
64 }
65
66 // Prune performs the pruning operation in-place.
67 func (z *Scalar) Prune() {
68         z[0] &= 248
69         z[31] &= 127
70         z[31] |= 64
71 }
72
73 // Reduce takes a 512-bit scalar and reduces it mod L, placing the
74 // result in z and returning that.
75 func (z *Scalar) Reduce(x *[64]byte) *Scalar {
76         edwards25519.ScReduce((*[32]byte)(z), x)
77         return z
78 }