edwards25519

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 11, 2024 License: BSD-3-Clause Imports: 15 Imported by: 3

README

edwards25519

This repo is out of maintenance and decommissioned.

Documentation

Overview

Package edwards25519 implements operations in GF(2**255-19) and on an Edwards curve that is isomorphic to curve25519. See http://ed25519.cr.yp.to/.

Index

Constants

View Source
const (
	PublicKeySize  = 32
	PrivateKeySize = 64

	// SignatureSize is the size of an encoded ECDSA signature.
	SignatureSize = 64
)
View Source
const (
	PrivScalarSize  = 32
	PrivKeyBytesLen = 64
)

These constants define the lengths of serialized private keys.

View Source
const (
	PubKeyBytesLen = 32
)

These constants define the lengths of serialized public keys.

Variables

View Source
var A = FieldElement{
	486662, 0, 0, 0, 0, 0, 0, 0, 0, 0,
}
View Source
var (
	// ErrInvalidMAC occurs when Message Authentication Check (MAC) fails
	// during decryption. This happens because of either invalid private key or
	// corrupt ciphertext.
	ErrInvalidMAC = errors.New("invalid mac hash")
)
View Source
var Sha512VersionStringRFC6979 = []byte("Edwards+SHA512  ")

Sha512VersionStringRFC6979 is the RFC6979 nonce version for a Schnorr signature over the Curve25519 curve using BLAKE256 as the hash function.

View Source
var SqrtM1 = FieldElement{
	-32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482,
}

Functions

func Decrypt

func Decrypt(priv *PrivateKey, in []byte) ([]byte, error)

Decrypt decrypts data that was encrypted using the Encrypt function.

func Encrypt

func Encrypt(pubkey *PublicKey, in []byte) ([]byte, error)

Encrypt encrypts data for the target public key using AES-256-CBC. It also generates a private key (the pubkey of which is also in the output).

struct {
	// Initialization Vector used for AES-256-CBC
	IV [16]byte
	// Public Key: curve(2) + len_of_pubkeyX(2) + pubkeyY (curve = 0xFFFF)
	PublicKey [36]byte
	// Cipher text
	Data []byte
	// HMAC-SHA-256 Message Authentication Code
	HMAC [32]byte
}

The primary aim is to ensure byte compatibility with Pyelliptic. Additionally, refer to section 5.8.1 of ANSI X9.63 for rationale on this format.

func FeAdd

func FeAdd(dst, a, b *FieldElement)

func FeCMove

func FeCMove(f, g *FieldElement, b int32)

Replace (f,g) with (g,g) if b == 1; replace (f,g) with (f,g) if b == 0.

Preconditions: b in {0,1}.

func FeCombine

func FeCombine(h *FieldElement, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9 int64)

func FeCopy

func FeCopy(dst, src *FieldElement)

func FeFromBytes

func FeFromBytes(dst *FieldElement, src *[32]byte)

func FeInvert

func FeInvert(out, z *FieldElement)

func FeIsNegative

func FeIsNegative(f *FieldElement) byte

func FeIsNonZero

func FeIsNonZero(f *FieldElement) int32

func FeMul

func FeMul(h, f, g *FieldElement)

FeMul calculates h = f * g Can overlap h with f or g.

Preconditions:

|f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|g| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.

Postconditions:

|h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.

Notes on implementation strategy:

Using schoolbook multiplication. Karatsuba would save a little in some cost models.

Most multiplications by 2 and 19 are 32-bit precomputations; cheaper than 64-bit postcomputations.

There is one remaining multiplication by 19 in the carry chain; one *19 precomputation can be merged into this, but the resulting data flow is considerably less clean.

There are 12 carries below. 10 of them are 2-way parallelizable and vectorizable. Can get away with 11 carries, but then data flow is much deeper.

With tighter constraints on inputs can squeeze carries into int32.

func FeNeg

func FeNeg(h, f *FieldElement)

FeNeg sets h = -f

Preconditions:

|f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.

Postconditions:

|h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.

func FeOne

func FeOne(fe *FieldElement)

func FeSquare

func FeSquare(h, f *FieldElement)

FeSquare calculates h = f*f. Can overlap h with f.

Preconditions:

|f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.

Postconditions:

|h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.

func FeSquare2

func FeSquare2(h, f *FieldElement)

FeSquare2 sets h = 2 * f * f

Can overlap h with f.

Preconditions:

|f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.

Postconditions:

|h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.

See fe_mul.c for discussion of implementation strategy.

func FeSub

func FeSub(dst, a, b *FieldElement)

func FeToBytes

func FeToBytes(s *[32]byte, h *FieldElement)

FeToBytes marshals h to s. Preconditions:

|h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.

Write p=2^255-19; q=floor(h/p). Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).

Proof:

Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.
Also have |h-2^230 h9|<2^230 so |19 2^(-255)(h-2^230 h9)|<1/4.

Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).
Then 0<y<1.

Write r=h-pq.
Have 0<=r<=p-1=2^255-20.
Thus 0<=r+19(2^-255)r<r+19(2^-255)2^255<=2^255-1.

Write x=r+19(2^-255)r+y.
Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q.

Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1))
so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q.

func FeZero

func FeZero(fe *FieldElement)

func GeDoubleScalarMultVartime

func GeDoubleScalarMultVartime(r *ProjectiveGroupElement, a *[32]byte, A *ExtendedGroupElement, b *[32]byte)

GeDoubleScalarMultVartime sets r = a*A + b*B where a = a[0]+256*a[1]+...+256^31 a[31]. and b = b[0]+256*b[1]+...+256^31 b[31]. B is the Ed25519 base point (x,4/5) with x positive.

func GeScalarMultBase

func GeScalarMultBase(h *ExtendedGroupElement, a *[32]byte)

GeScalarMultBase computes h = a*B, where

a = a[0]+256*a[1]+...+256^31 a[31]
B is the Ed25519 base point (x,4/5) with x positive.

Preconditions:

a[31] <= 127

func GenerateKey

func GenerateKey(rand io.Reader) (publicKey *[PublicKeySize]byte, privateKey *[PrivateKeySize]byte, err error)

GenerateKey generates a public/private key pair using randomness from rand.

func GenerateKeyXY

func GenerateKeyXY(rand io.Reader) (priv []byte, x, y *big.Int, err error)

GenerateKey generates a key using a random number generator, returning the private scalar and the corresponding public key points from a random secret.

func GenerateSharedSecret

func GenerateSharedSecret(privkey *PrivateKey, pubkey *PublicKey) []byte

GenerateSharedSecret generates a shared secret based on a private key and a private key using Diffie-Hellman key exchange (ECDH) (RFC 4753). RFC5903 Section 9 states we should only return y.

func NonceRFC6979

func NonceRFC6979(privkey *big.Int, hash []byte, extra []byte, version []byte) *big.Int

NonceRFC6979 generates an ECDSA nonce (`k`) deterministically according to RFC 6979. It takes a 32-byte hash as an input and returns 32-byte nonce to be used in ECDSA algorithm.

func PreComputedGroupElementCMove

func PreComputedGroupElementCMove(t, u *PreComputedGroupElement, b int32)

func PrivKeyFromBytes

func PrivKeyFromBytes(pkBytes []byte) (*PrivateKey, *PublicKey)

PrivKeyFromBytes returns a private and public key for `curve' based on the private key passed as an argument as a byte slice.

func PrivKeyFromScalar

func PrivKeyFromScalar(p []byte) (*PrivateKey, *PublicKey, error)

PrivKeyFromScalar returns a private and public key for `curve' based on the 32-byte private scalar passed as an argument as a byte slice (encoded big endian int).

func PrivKeyFromSecret

func PrivKeyFromSecret(s []byte) (*PrivateKey, *PublicKey)

PrivKeyFromSecret returns a private and public key for `curve' based on the 32-byte private key secret passed as an argument as a byte slice.

func ScMulAdd

func ScMulAdd(s, a, b, c *[32]byte)

Input:

a[0]+256*a[1]+...+256^31*a[31] = a
b[0]+256*b[1]+...+256^31*b[31] = b
c[0]+256*c[1]+...+256^31*c[31] = c

Output:

s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
where l = 2^252 + 27742317777372353535851937790883648493.

func ScReduce

func ScReduce(out *[32]byte, s *[64]byte)

Input:

s[0]+256*s[1]+...+256^63*s[63] = s

Output:

s[0]+256*s[1]+...+256^31*s[31] = s mod l
where l = 2^252 + 27742317777372353535851937790883648493.

func Sign

func Sign(privateKey *[PrivateKeySize]byte, message []byte) *[SignatureSize]byte

Sign signs the message with privateKey and returns a signature.

func SignFromScalar

func SignFromScalar(priv *PrivateKey, nonce []byte, hash []byte) (r, s *big.Int, err error)

SignFromScalar signs a message 'hash' using the given private scalar priv. It uses RFC6979 to generate a deterministic nonce. Considered experimental. r = kG, where k is the RFC6979 nonce s = r + hash512(k || A || M) * a

func SignFromSecret

func SignFromSecret(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error)

SignFromSecret signs a message 'hash' using the given private key priv. It doesn't actually user the random reader (the lib is maybe deterministic???).

func SignFromSecretNoReader

func SignFromSecretNoReader(priv *PrivateKey, hash []byte) (r, s *big.Int, err error)

SignFromSecretNoReader signs a message 'hash' using the given private key priv. It doesn't actually user the random reader.

func SignRS

func SignRS(priv *PrivateKey, hash []byte) (r, s *big.Int, err error)

Sign is the generalized and exported version of Ed25519 signing, that handles both standard private secrets and non-standard scalars.

func SignThreshold

func SignThreshold(priv *PrivateKey, groupPub *PublicKey, hash []byte, privNonce *PrivateKey,
	pubNonceSum *PublicKey) (r, s *big.Int, err error)

SignThreshold signs a message 'hash' using the given private scalar priv in a threshold group signature. It uses RFC6979 to generate a deterministic nonce. Considered experimental. As opposed to the threshold signing function for secp256k1, this function takes the entirety of the public nonce point (all points added) instead of the public nonce point with n-1 keys added. r = K_Sum s = r + hash512(k || A || M) * a

func Verify

func Verify(publicKey *[PublicKeySize]byte, message []byte, sig *[SignatureSize]byte) bool

Verify returns true iff sig is a valid signature of message by publicKey.

func VerifyRS

func VerifyRS(pub *PublicKey, hash []byte, r, s *big.Int) bool

Verify verifies a message 'hash' using the given public keys and signature.

Types

type CachedGroupElement

type CachedGroupElement struct {
	Z, T2d FieldElement
	// contains filtered or unexported fields
}

type CompletedGroupElement

type CompletedGroupElement struct {
	X, Y, Z, T FieldElement
}

func (*CompletedGroupElement) ToExtended

func (p *CompletedGroupElement) ToExtended(r *ExtendedGroupElement)

func (*CompletedGroupElement) ToProjective

func (p *CompletedGroupElement) ToProjective(r *ProjectiveGroupElement)

type ExtendedGroupElement

type ExtendedGroupElement struct {
	X, Y, Z, T FieldElement
}

func (*ExtendedGroupElement) Double

func (*ExtendedGroupElement) FromBytes

func (p *ExtendedGroupElement) FromBytes(s *[32]byte) bool

func (*ExtendedGroupElement) ToBytes

func (p *ExtendedGroupElement) ToBytes(s *[32]byte)

func (*ExtendedGroupElement) ToCached

func (p *ExtendedGroupElement) ToCached(r *CachedGroupElement)

func (*ExtendedGroupElement) ToProjective

func (p *ExtendedGroupElement) ToProjective(r *ProjectiveGroupElement)

func (*ExtendedGroupElement) Zero

func (p *ExtendedGroupElement) Zero()

type FieldElement

type FieldElement [10]int32

FieldElement represents an element of the field GF(2^255 - 19). An element t, entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on context.

type PreComputedGroupElement

type PreComputedGroupElement struct {
	// contains filtered or unexported fields
}

func (*PreComputedGroupElement) Zero

func (p *PreComputedGroupElement) Zero()

type PrivateKey

type PrivateKey struct {
	// contains filtered or unexported fields
}

PrivateKey wraps an ecdsa.PrivateKey as a convenience mainly for signing things with the private key without having to directly import the ecdsa package.

func GeneratePrivateKey

func GeneratePrivateKey() (*PrivateKey, error)

GeneratePrivateKey is a wrapper for ecdsa.GenerateKey that returns a PrivateKey instead of the normal ecdsa.PrivateKey.

func NewPrivateKey

func NewPrivateKey(d *big.Int) *PrivateKey

NewPrivateKey instantiates a new private key from a scalar encoded as a big integer.

func (PrivateKey) GetD

func (p PrivateKey) GetD() *big.Int

GetD satisfies the chainec PrivateKey interface.

func (PrivateKey) GetType

func (p PrivateKey) GetType() int

GetType satisfies the chainec PrivateKey interface.

func (*PrivateKey) PubKey

func (p *PrivateKey) PubKey() *PublicKey

PubKey returns the PublicKey corresponding to this private key.

func (PrivateKey) Public

func (p PrivateKey) Public() (*big.Int, *big.Int)

Public returns the PublicKey corresponding to this private key.

func (PrivateKey) Serialize

func (p PrivateKey) Serialize() []byte

Serialize returns the private key as a 32 byte big endian number.

func (PrivateKey) SerializeSecret

func (p PrivateKey) SerializeSecret() []byte

SerializeSecret returns the 32 byte secret along with its public key as 64 bytes.

func (PrivateKey) Sign

func (p PrivateKey) Sign(hash []byte) (*Signature, error)

Sign is the generalized and exported version of Ed25519 signing, that handles both standard private secrets and non-standard scalars.

func (PrivateKey) ToECDSA

func (p PrivateKey) ToECDSA() *ecdsa.PrivateKey

ToECDSA returns the private key as a *ecdsa.PrivateKey.

type ProjectiveGroupElement

type ProjectiveGroupElement struct {
	X, Y, Z FieldElement
}

func (*ProjectiveGroupElement) Double

func (*ProjectiveGroupElement) ToBytes

func (p *ProjectiveGroupElement) ToBytes(s *[32]byte)

func (*ProjectiveGroupElement) Zero

func (p *ProjectiveGroupElement) Zero()

type PublicKey

type PublicKey ecdsa.PublicKey

PublicKey is an ecdsa.PublicKey with an additional function to serialize.

func NewPublicKey

func NewPublicKey(x *big.Int, y *big.Int) *PublicKey

NewPublicKey instantiates a new public key.

func ParsePubKey

func ParsePubKey(pubKeyStr []byte) (key *PublicKey, err error)

ParsePubKey parses a public key for an edwards curve from a bytestring into a ecdsa.Publickey, verifying that it is valid.

func RecoverCompact

func RecoverCompact(signature, hash []byte) (*PublicKey, bool, error)

RecoverCompact uses a signature and a hash to recover is private key, is not yet implemented. TODO: Implement.

func (PublicKey) GetCurve

func (p PublicKey) GetCurve() interface{}

GetCurve satisfies the chainec PublicKey interface.

func (PublicKey) GetType

func (p PublicKey) GetType() int

GetType satisfies the chainec PublicKey interface.

func (PublicKey) GetX

func (p PublicKey) GetX() *big.Int

GetX satisfies the chainec PublicKey interface.

func (PublicKey) GetY

func (p PublicKey) GetY() *big.Int

GetY satisfies the chainec PublicKey interface.

func (PublicKey) Serialize

func (p PublicKey) Serialize() []byte

Serialize serializes a public key in a 32-byte compressed little endian format.

func (PublicKey) SerializeCompressed

func (p PublicKey) SerializeCompressed() []byte

SerializeCompressed satisfies the chainec PublicKey interface.

func (PublicKey) SerializeUncompressed

func (p PublicKey) SerializeUncompressed() []byte

SerializeUncompressed satisfies the chainec PublicKey interface.

func (PublicKey) ToECDSA

func (p PublicKey) ToECDSA() *ecdsa.PublicKey

ToECDSA returns the public key as a *ecdsa.PublicKey.

type Signature

type Signature struct {
	R *big.Int
	S *big.Int
}

Signature is a type representing an ecdsa signature.

func NewSignature

func NewSignature(r, s *big.Int) *Signature

NewSignature instantiates a new signature given some R,S values.

func ParseDERSignature

func ParseDERSignature(sigStr []byte) (*Signature, error)

ParseDERSignature offers a legacy function for plugging into Decred, which is based off btcec.

func ParseSignature

func ParseSignature(sigStr []byte) (*Signature, error)

ParseSignature parses a signature in BER format for the curve type `curve' into a Signature type, performing some basic sanity checks.

func (Signature) GetR

func (sig Signature) GetR() *big.Int

GetR satisfies the chainec Signature interface.

func (Signature) GetS

func (sig Signature) GetS() *big.Int

GetS satisfies the chainec Signature interface.

func (Signature) GetType

func (sig Signature) GetType() int

GetType satisfies the chainec Signature interface.

func (*Signature) IsEqual

func (sig *Signature) IsEqual(otherSig *Signature) bool

IsEqual compares this Signature instance to the one passed, returning true if both Signatures are equivalent. A signature is equivalent to another, if they both have the same scalar value for R and S.

func (Signature) Serialize

func (sig Signature) Serialize() []byte

Serialize returns the ECDSA signature in the more strict format.

The signatures are encoded as

sig[0:32]  R, a point encoded as little endian
sig[32:64] S, scalar multiplication/addition results = (ab+c) mod l
  encoded also as little endian

func (*Signature) Verify

func (sig *Signature) Verify(hash []byte, pubKey *PublicKey) bool

Verify verifies a message 'hash' using the given public keys and signature.

type TwistedEdwardsCurve

type TwistedEdwardsCurve struct {
	*elliptic.CurveParams
	H int // Cofactor of the curve

	A, D, I *big.Int // Edwards curve equation parameter constants
	// contains filtered or unexported fields
}

TwistedEdwardsCurve extended an elliptical curve set of parameters to satisfy the interface of the elliptic package.

func Edwards

func Edwards() *TwistedEdwardsCurve

Edwards returns a Curve which implements Ed25519.

func (*TwistedEdwardsCurve) Add

func (curve *TwistedEdwardsCurve) Add(x1, y1, x2, y2 *big.Int) (x, y *big.Int)

Add adds two points represented by pairs of big integers on the elliptical curve.

func (*TwistedEdwardsCurve) Double

func (curve *TwistedEdwardsCurve) Double(x1, y1 *big.Int) (x, y *big.Int)

Double adds the same pair of big integer coordinates to itself on the elliptical curve.

func (*TwistedEdwardsCurve) IsOnCurve

func (curve *TwistedEdwardsCurve) IsOnCurve(x *big.Int, y *big.Int) bool

IsOnCurve returns bool to say if the point (x,y) is on the curve by checking (y^2 - x^2 - 1 - dx^2y^2) % P == 0.

func (TwistedEdwardsCurve) Params

func (curve TwistedEdwardsCurve) Params() *elliptic.CurveParams

Params returns the parameters for the curve.

func (*TwistedEdwardsCurve) ScalarBaseMult

func (curve *TwistedEdwardsCurve) ScalarBaseMult(k []byte) (x, y *big.Int)

ScalarBaseMult returns k*G, where G is the base point of the group and k is an integer in big-endian form. TODO Optimize this with field elements

func (*TwistedEdwardsCurve) ScalarMult

func (curve *TwistedEdwardsCurve) ScalarMult(x1, y1 *big.Int, k []byte) (x, y *big.Int)

ScalarMult returns k*(Bx,By) where k is a number in big-endian form. This uses the repeated doubling method, which is variable time. TODO use a constant time method to prevent side channel attacks.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL