OSDN Git Service

Hulk did something
[bytom/vapor.git] / crypto / ed25519 / ecmath / scalar.go
diff --git a/crypto/ed25519/ecmath/scalar.go b/crypto/ed25519/ecmath/scalar.go
new file mode 100644 (file)
index 0000000..d3ab1c1
--- /dev/null
@@ -0,0 +1,78 @@
+package ecmath
+
+import (
+       "crypto/subtle"
+
+       "github.com/vapor/crypto/ed25519/internal/edwards25519"
+)
+
+// Scalar is a 256-bit little-endian scalar.
+type Scalar [32]byte
+
+var (
+       // Zero is the number 0.
+       Zero Scalar
+
+       // One is the number 1.
+       One = Scalar{1}
+
+       // NegOne is the number -1 mod L
+       NegOne = Scalar{
+               0xec, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
+               0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+       }
+
+       // L is the subgroup order:
+       // 2^252 + 27742317777372353535851937790883648493
+       L = Scalar{
+               0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
+               0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+       }
+)
+
+// Add computes x+y (mod L) and places the result in z, returning
+// that. Any or all of x, y, and z may be the same pointer.
+func (z *Scalar) Add(x, y *Scalar) *Scalar {
+       return z.MulAdd(x, &One, y)
+}
+
+// Sub computes x-y (mod L) and places the result in z, returning
+// that. Any or all of x, y, and z may be the same pointer.
+func (z *Scalar) Sub(x, y *Scalar) *Scalar {
+       return z.MulAdd(y, &NegOne, x)
+}
+
+// Neg negates x (mod L) and places the result in z, returning that. X
+// and z may be the same pointer.
+func (z *Scalar) Neg(x *Scalar) *Scalar {
+       return z.MulAdd(x, &NegOne, &Zero)
+}
+
+// MulAdd computes ab+c (mod L) and places the result in z, returning
+// that. Any or all of the pointers may be the same.
+func (z *Scalar) MulAdd(a, b, c *Scalar) *Scalar {
+       edwards25519.ScMulAdd((*[32]byte)(z), (*[32]byte)(a), (*[32]byte)(b), (*[32]byte)(c))
+       return z
+}
+
+func (z *Scalar) Equal(x *Scalar) bool {
+       return subtle.ConstantTimeCompare(x[:], z[:]) == 1
+}
+
+// Prune performs the pruning operation in-place.
+func (z *Scalar) Prune() {
+       z[0] &= 248
+       z[31] &= 127
+       z[31] |= 64
+}
+
+// Reduce takes a 512-bit scalar and reduces it mod L, placing the
+// result in z and returning that.
+func (z *Scalar) Reduce(x *[64]byte) *Scalar {
+       edwards25519.ScReduce((*[32]byte)(z), x)
+       return z
+}