// Copyright 2013 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 ellipticimport ()// p384Curve is a Curve implementation based on nistec.P384Point.//// It's a wrapper that exposes the big.Int-based Curve interface and encodes the// legacy idiosyncrasies it requires, such as invalid and infinity point// handling.//// To interact with the nistec package, points are encoded into and decoded from// properly formatted byte slices. All big.Int use is limited to this package.// Encoding and decoding is 1/1000th of the runtime of a scalar multiplication,// so the overhead is acceptable.typep384Curvestruct {params *CurveParams}varp384p384Curvevar _ Curve = p384func () {p384.params = &CurveParams{Name: "P-384",BitSize: 384,// FIPS 186-4, section D.1.2.4P: bigFromDecimal("394020061963944792122790401001436138050797392704654" +"46667948293404245721771496870329047266088258938001861606973112319"),N: bigFromDecimal("394020061963944792122790401001436138050797392704654" +"46667946905279627659399113263569398956308152294913554433653942643"),B: bigFromHex("b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088" +"f5013875ac656398d8a2ed19d2a85c8edd3ec2aef"),Gx: bigFromHex("aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741" +"e082542a385502f25dbf55296c3a545e3872760ab7"),Gy: bigFromHex("3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da31" +"13b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f"), }}func ( p384Curve) () *CurveParams {return .params}func ( p384Curve) (, *big.Int) bool {// IsOnCurve is documented to reject (0, 0), the conventional point at // infinity, which however is accepted by p384PointFromAffine.if .Sign() == 0 && .Sign() == 0 {returnfalse } , := p384PointFromAffine(, )return}func (, *big.Int) ( *nistec.P384Point, bool) {// (0, 0) is by convention the point at infinity, which can't be represented // in affine coordinates. Marshal incorrectly encodes it as an uncompressed // point, which SetBytes would correctly reject. See Issue 37294.if .Sign() == 0 && .Sign() == 0 {returnnistec.NewP384Point(), true }if .Sign() < 0 || .Sign() < 0 {returnnil, false }if .BitLen() > 384 || .BitLen() > 384 {returnnil, false } , := nistec.NewP384Point().SetBytes(Marshal(P384(), , ))if != nil {returnnil, false }return , true}func ( *nistec.P384Point) (, *big.Int) { := .Bytes()iflen() == 1 && [0] == 0 {// This is the correct encoding of the point at infinity, which // Unmarshal does not support. See Issue 37294.returnnew(big.Int), new(big.Int) } , = Unmarshal(P384(), )if == nil {panic("crypto/elliptic: internal error: Unmarshal rejected a valid point encoding") }return , }// p384RandomPoint returns a random point on the curve. It's used when Add,// Double, or ScalarMult are fed a point not on the curve, which is undefined// behavior. Originally, we used to do the math on it anyway (which allows// invalid curve attacks) and relied on the caller and Unmarshal to avoid this// happening in the first place. Now, we just can't construct a nistec.P384Point// for an invalid pair of coordinates, because that API is safer. If we panic,// we risk introducing a DoS. If we return nil, we risk a panic. If we return// the input, ecdsa.Verify might fail open. The safest course seems to be to// return a valid, random point, which hopefully won't help the attacker.func () (, *big.Int) { , , , := GenerateKey(P384(), rand.Reader)if != nil {panic("crypto/elliptic: failed to generate random point") }return , }func (p384Curve) (, , , *big.Int) (*big.Int, *big.Int) { , := p384PointFromAffine(, )if ! {returnp384RandomPoint() } , := p384PointFromAffine(, )if ! {returnp384RandomPoint() }returnp384PointToAffine(.Add(, ))}func (p384Curve) (, *big.Int) (*big.Int, *big.Int) { , := p384PointFromAffine(, )if ! {returnp384RandomPoint() }returnp384PointToAffine(.Double())}func (p384Curve) (, *big.Int, []byte) (*big.Int, *big.Int) { , := p384PointFromAffine(, )if ! {returnp384RandomPoint() }returnp384PointToAffine(.ScalarMult(, ))}func (p384Curve) ( []byte) (*big.Int, *big.Int) { := nistec.NewP384Generator()returnp384PointToAffine(.ScalarMult(, ))}
The pages are generated with Goldsv0.4.9. (GOOS=linux GOARCH=amd64)