PNG  IHDR  8] PLTE S =tRNS   PNG  IHDR  8] PLTE S =tRNS   REDROOM
PHP 7.4.33
Preview: elliptic.go Size: 9.02 KB
/proc/thread-self/root/opt/golang/1.22.0/src/crypto/elliptic/elliptic.go

// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package elliptic implements the standard NIST P-224, P-256, P-384, and P-521
// elliptic curves over prime fields.
//
// Direct use of this package is deprecated, beyond the [P224], [P256], [P384],
// and [P521] values necessary to use [crypto/ecdsa]. Most other uses
// should migrate to the more efficient and safer [crypto/ecdh], or to
// third-party modules for lower-level functionality.
package elliptic

import (
	"io"
	"math/big"
	"sync"
)

// A Curve represents a short-form Weierstrass curve with a=-3.
//
// The behavior of Add, Double, and ScalarMult when the input is not a point on
// the curve is undefined.
//
// Note that the conventional point at infinity (0, 0) is not considered on the
// curve, although it can be returned by Add, Double, ScalarMult, or
// ScalarBaseMult (but not the [Unmarshal] or [UnmarshalCompressed] functions).
//
// Using Curve implementations besides those returned by [P224], [P256], [P384],
// and [P521] is deprecated.
type Curve interface {
	// Params returns the parameters for the curve.
	Params() *CurveParams

	// IsOnCurve reports whether the given (x,y) lies on the curve.
	//
	// Deprecated: this is a low-level unsafe API. For ECDH, use the crypto/ecdh
	// package. The NewPublicKey methods of NIST curves in crypto/ecdh accept
	// the same encoding as the Unmarshal function, and perform on-curve checks.
	IsOnCurve(x, y *big.Int) bool

	// Add returns the sum of (x1,y1) and (x2,y2).
	//
	// Deprecated: this is a low-level unsafe API.
	Add(x1, y1, x2, y2 *big.Int) (x, y *big.Int)

	// Double returns 2*(x,y).
	//
	// Deprecated: this is a low-level unsafe API.
	Double(x1, y1 *big.Int) (x, y *big.Int)

	// ScalarMult returns k*(x,y) where k is an integer in big-endian form.
	//
	// Deprecated: this is a low-level unsafe API. For ECDH, use the crypto/ecdh
	// package. Most uses of ScalarMult can be replaced by a call to the ECDH
	// methods of NIST curves in crypto/ecdh.
	ScalarMult(x1, y1 *big.Int, 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.
	//
	// Deprecated: this is a low-level unsafe API. For ECDH, use the crypto/ecdh
	// package. Most uses of ScalarBaseMult can be replaced by a call to the
	// PrivateKey.PublicKey method in crypto/ecdh.
	ScalarBaseMult(k []byte) (x, y *big.Int)
}

var mask = []byte{0xff, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f}

// GenerateKey returns a public/private key pair. The private key is
// generated using the given reader, which must return random data.
//
// Deprecated: for ECDH, use the GenerateKey methods of the [crypto/ecdh] package;
// for ECDSA, use the GenerateKey function of the crypto/ecdsa package.
func GenerateKey(curve Curve, rand io.Reader) (priv []byte, x, y *big.Int, err error) {
	N := curve.Params().N
	bitSize := N.BitLen()
	byteLen := (bitSize + 7) / 8
	priv = make([]byte, byteLen)

	for x == nil {
		_, err = io.ReadFull(rand, priv)
		if err != nil {
			return
		}
		// We have to mask off any excess bits in the case that the size of the
		// underlying field is not a whole number of bytes.
		priv[0] &= mask[bitSize%8]
		// This is because, in tests, rand will return all zeros and we don't
		// want to get the point at infinity and loop forever.
		priv[1] ^= 0x42

		// If the scalar is out of range, sample another random number.
		if new(big.Int).SetBytes(priv).Cmp(N) >= 0 {
			continue
		}

		x, y = curve.ScalarBaseMult(priv)
	}
	return
}

// Marshal converts a point on the curve into the uncompressed form specified in
// SEC 1, Version 2.0, Section 2.3.3. If the point is not on the curve (or is
// the conventional point at infinity), the behavior is undefined.
//
// Deprecated: for ECDH, use the crypto/ecdh package. This function returns an
// encoding equivalent to that of PublicKey.Bytes in crypto/ecdh.
func Marshal(curve Curve, x, y *big.Int) []byte {
	panicIfNotOnCurve(curve, x, y)

	byteLen := (curve.Params().BitSize + 7) / 8

	ret := make([]byte, 1+2*byteLen)
	ret[0] = 4 // uncompressed point

	x.FillBytes(ret[1 : 1+byteLen])
	y.FillBytes(ret[1+byteLen : 1+2*byteLen])

	return ret
}

// MarshalCompressed converts a point on the curve into the compressed form
// specified in SEC 1, Version 2.0, Section 2.3.3. If the point is not on the
// curve (or is the conventional point at infinity), the behavior is undefined.
func MarshalCompressed(curve Curve, x, y *big.Int) []byte {
	panicIfNotOnCurve(curve, x, y)
	byteLen := (curve.Params().BitSize + 7) / 8
	compressed := make([]byte, 1+byteLen)
	compressed[0] = byte(y.Bit(0)) | 2
	x.FillBytes(compressed[1:])
	return compressed
}

// unmarshaler is implemented by curves with their own constant-time Unmarshal.
//
// There isn't an equivalent interface for Marshal/MarshalCompressed because
// that doesn't involve any mathematical operations, only FillBytes and Bit.
type unmarshaler interface {
	Unmarshal([]byte) (x, y *big.Int)
	UnmarshalCompressed([]byte) (x, y *big.Int)
}

// Assert that the known curves implement unmarshaler.
var _ = []unmarshaler{p224, p256, p384, p521}

// Unmarshal converts a point, serialized by [Marshal], into an x, y pair. It is
// an error if the point is not in uncompressed form, is not on the curve, or is
// the point at infinity. On error, x = nil.
//
// Deprecated: for ECDH, use the crypto/ecdh package. This function accepts an
// encoding equivalent to that of the NewPublicKey methods in crypto/ecdh.
func Unmarshal(curve Curve, data []byte) (x, y *big.Int) {
	if c, ok := curve.(unmarshaler); ok {
		return c.Unmarshal(data)
	}

	byteLen := (curve.Params().BitSize + 7) / 8
	if len(data) != 1+2*byteLen {
		return nil, nil
	}
	if data[0] != 4 { // uncompressed form
		return nil, nil
	}
	p := curve.Params().P
	x = new(big.Int).SetBytes(data[1 : 1+byteLen])
	y = new(big.Int).SetBytes(data[1+byteLen:])
	if x.Cmp(p) >= 0 || y.Cmp(p) >= 0 {
		return nil, nil
	}
	if !curve.IsOnCurve(x, y) {
		return nil, nil
	}
	return
}

// UnmarshalCompressed converts a point, serialized by [MarshalCompressed], into
// an x, y pair. It is an error if the point is not in compressed form, is not
// on the curve, or is the point at infinity. On error, x = nil.
func UnmarshalCompressed(curve Curve, data []byte) (x, y *big.Int) {
	if c, ok := curve.(unmarshaler); ok {
		return c.UnmarshalCompressed(data)
	}

	byteLen := (curve.Params().BitSize + 7) / 8
	if len(data) != 1+byteLen {
		return nil, nil
	}
	if data[0] != 2 && data[0] != 3 { // compressed form
		return nil, nil
	}
	p := curve.Params().P
	x = new(big.Int).SetBytes(data[1:])
	if x.Cmp(p) >= 0 {
		return nil, nil
	}
	// y² = x³ - 3x + b
	y = curve.Params().polynomial(x)
	y = y.ModSqrt(y, p)
	if y == nil {
		return nil, nil
	}
	if byte(y.Bit(0)) != data[0]&1 {
		y.Neg(y).Mod(y, p)
	}
	if !curve.IsOnCurve(x, y) {
		return nil, nil
	}
	return
}

func panicIfNotOnCurve(curve Curve, x, y *big.Int) {
	// (0, 0) is the point at infinity by convention. It's ok to operate on it,
	// although IsOnCurve is documented to return false for it. See Issue 37294.
	if x.Sign() == 0 && y.Sign() == 0 {
		return
	}

	if !curve.IsOnCurve(x, y) {
		panic("crypto/elliptic: attempted operation on invalid point")
	}
}

var initonce sync.Once

func initAll() {
	initP224()
	initP256()
	initP384()
	initP521()
}

// P224 returns a [Curve] which implements NIST P-224 (FIPS 186-3, section D.2.2),
// also known as secp224r1. The CurveParams.Name of this [Curve] is "P-224".
//
// Multiple invocations of this function will return the same value, so it can
// be used for equality checks and switch statements.
//
// The cryptographic operations are implemented using constant-time algorithms.
func P224() Curve {
	initonce.Do(initAll)
	return p224
}

// P256 returns a [Curve] which implements NIST P-256 (FIPS 186-3, section D.2.3),
// also known as secp256r1 or prime256v1. The CurveParams.Name of this [Curve] is
// "P-256".
//
// Multiple invocations of this function will return the same value, so it can
// be used for equality checks and switch statements.
//
// The cryptographic operations are implemented using constant-time algorithms.
func P256() Curve {
	initonce.Do(initAll)
	return p256
}

// P384 returns a [Curve] which implements NIST P-384 (FIPS 186-3, section D.2.4),
// also known as secp384r1. The CurveParams.Name of this [Curve] is "P-384".
//
// Multiple invocations of this function will return the same value, so it can
// be used for equality checks and switch statements.
//
// The cryptographic operations are implemented using constant-time algorithms.
func P384() Curve {
	initonce.Do(initAll)
	return p384
}

// P521 returns a [Curve] which implements NIST P-521 (FIPS 186-3, section D.2.5),
// also known as secp521r1. The CurveParams.Name of this [Curve] is "P-521".
//
// Multiple invocations of this function will return the same value, so it can
// be used for equality checks and switch statements.
//
// The cryptographic operations are implemented using constant-time algorithms.
func P521() Curve {
	initonce.Do(initAll)
	return p521
}

Directory Contents

Dirs: 0 × Files: 7

Name Size Perms Modified Actions
9.02 KB lrw-r--r-- 2024-02-02 18:09:55
Edit Download
11.58 KB lrw-r--r-- 2024-02-02 18:09:55
Edit Download
9.55 KB lrw-r--r-- 2024-02-02 18:09:55
Edit Download
696 B lrw-r--r-- 2024-02-02 18:09:55
Edit Download
10.70 KB lrw-r--r-- 2024-02-02 18:09:55
Edit Download
4.15 KB lrw-r--r-- 2024-02-02 18:09:55
Edit Download
9.58 KB lrw-r--r-- 2024-02-02 18:09:55
Edit Download

If ZipArchive is unavailable, a .tar will be created (no compression).
 !"#$%&'(()*+,-./00123456789 t\ wIDATx ]ys  47Y ƒ -  "  Rv  < f{Ɛ $k l L > L  ~h^ 1  [  r G t& h  l F z3O Y ! p A(_g̷ E8 )S 8 c  Kb"z ~ 5 J xAL WU <  *  5 m;W a pB h ~P J 2 3 6 ҙ .Ƹ P i  4g F R L P ΪK/D  M v (a3 k J Œ4N5* SH ` SdJ z  O J Xՠ V>u ߱ BE&L b2 ?2` tX+  c CB A$ i b C ĀMB E : /  # Dx &l =q Ty  0 \p I ( L Ǎ { e 4k ;`u^ヲ eP!( d {  )T A 8 O;Ě n >;s6 !  :Nx `[S D HU ~ q›J F} a g*D 49 / pn k h (t 8NxƐF _!r չ7 ZR R׷ q/5") Ӎ NY 0 x sZ!   o  fu  ,  K"$ ? pg  㕣=  1» {h " fh7    y  } € +7  $ y " X —ą - G P u 4 m >J 5 L =V ' ^@I p ?MS xЌ XV P ! h "C NS9B8̢ ]!K  e   zA , ӏkbY  !< XQ ٿyS| *" f { w  4@[S <  # 0 ! js [m  =,~ o "ݎ DHf Wo $ g ! Vԅ t mB /y Wf V4񺍸 c+@x?  B ~u " xUN e 0 BĂ) ~J pz! 7y6]l Ԥ@ P a< O /DHC `≻  N m"$  0ObB }{ x AO FCG D R ^ "B  { WDH  UR l@ T #  +"d T ; 0 i  D}. 7 ` ' ] w rE &S i ƕiTD EL P _ u h $ Ա FG wVD G L R Zf ' .!] J /ZR oGЍs Mr Ĥ ʬ 3 Q [3 cL ` ^ p + ( F;# B 5 '  2Y f [  ϶R0e }  E 7 6M aۮ H <& n % L] E}Up x紉, Uw' Q  Ǯշo k ވۙ 0N94 VX5 xEDE l D #֤ } C o )W :  ^ s 9  bRf iX5u ཱི 4 :[  T 1. | [E 2ؽ Iy\ : o x K G 5 ylP ' uK E ftb/i[3 .g _  [3M n G, #NwQ5~  ؚ) | n =Ц"x qg gB ` 듘 ~ x w ? ? R~  _ u. &VQ K˻   H C ( TN˄+ `C dA nB׭ D 3"Z G ê ^k H_ /- ~ " R_  .8 Z_ 6@ o  xg  uP ? 3լ @7AM!  E7^ - =V L  x  g-D0  CtmW 7  O  G _ WD0 g C  w1 r d w : a | \  *" f nֳ ^ H# f L ` Z ۽hV  }S F r0Ù Bć5r] @! NL iQ]{s^=4 d  WD  "  "   M; t" 8 5 e dL| "-*st" ) SWD ?R[S e ooF  20.D ? bo =) A i o d ģ ZҰaO @E =) i D a &ܟa CϞ y6 ,<%{^x%{f8? `iw^ ?/ M * IEND B`