// 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 ()// p224Curve is a Curve implementation based on nistec.P224Point.//// 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.typep224Curvestruct {params *CurveParams}varp224p224Curvevar _ Curve = p224func () {p224.params = &CurveParams{Name: "P-224",BitSize: 224,// FIPS 186-4, section D.1.2.2P: bigFromDecimal("26959946667150639794667015087019630673557916260026308143510066298881"),N: bigFromDecimal("26959946667150639794667015087019625940457807714424391721682722368061"),B: bigFromHex("b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4"),Gx: bigFromHex("b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21"),Gy: bigFromHex("bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34"), }}func ( p224Curve) () *CurveParams {return .params}func ( p224Curve) (, *big.Int) bool {// IsOnCurve is documented to reject (0, 0), the conventional point at // infinity, which however is accepted by p224PointFromAffine.if .Sign() == 0 && .Sign() == 0 {returnfalse } , := p224PointFromAffine(, )return}func (, *big.Int) ( *nistec.P224Point, 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.NewP224Point(), true }if .Sign() < 0 || .Sign() < 0 {returnnil, false }if .BitLen() > 224 || .BitLen() > 224 {returnnil, false } , := nistec.NewP224Point().SetBytes(Marshal(P224(), , ))if != nil {returnnil, false }return , true}func ( *nistec.P224Point) (, *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(P224(), )if == nil {panic("crypto/elliptic: internal error: Unmarshal rejected a valid point encoding") }return , }// p224RandomPoint 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.P224Point// 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(P224(), rand.Reader)if != nil {panic("crypto/elliptic: failed to generate random point") }return , }func (p224Curve) (, , , *big.Int) (*big.Int, *big.Int) { , := p224PointFromAffine(, )if ! {returnp224RandomPoint() } , := p224PointFromAffine(, )if ! {returnp224RandomPoint() }returnp224PointToAffine(.Add(, ))}func (p224Curve) (, *big.Int) (*big.Int, *big.Int) { , := p224PointFromAffine(, )if ! {returnp224RandomPoint() }returnp224PointToAffine(.Double())}func (p224Curve) (, *big.Int, []byte) (*big.Int, *big.Int) { , := p224PointFromAffine(, )if ! {returnp224RandomPoint() }returnp224PointToAffine(.ScalarMult(, ))}func (p224Curve) ( []byte) (*big.Int, *big.Int) { := nistec.NewP224Generator()returnp224PointToAffine(.ScalarMult(, ))}
The pages are generated with Goldsv0.4.9. (GOOS=linux GOARCH=amd64)