// This file is dual licensed under the terms of the Apache License, Version
// 2.0, and the BSD License. See the LICENSE file in the root of this repository
// for complete details.

use crate::common::{Curve, FieldID, FieldParameters, SpecifiedECDomain};

const P256_FIELD: FieldID<'static> = FieldID {
    field_type: asn1::DefinedByMarker::marker(),
    parameters: FieldParameters::PrimeField(asn1::BigUint::new(b"\x00\xff\xff\xff\xff\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff").unwrap()),
};
const P256_CURVE_A: &[u8; 32] = b"\xff\xff\xff\xff\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfc";
const P256_CURVE_B: &[u8; 32] = b"\x5a\xc6\x35\xd8\xaa\x3a\x93\xe7\xb3\xeb\xbd\x55\x76\x98\x86\xbc\x65\x1d\x06\xb0\xcc\x53\xb0\xf6\x3b\xce\x3c\x3e\x27\xd2\x60\x4b";
const P256_SEED: asn1::BitString<'static> = asn1::BitString::new(
    b"\xc4\x9d\x36\x08\x86\xe7\x04\x93\x6a\x66\x78\xe1\x13\x9d\x26\xb7\x81\x9f\x7e\x90",
    0,
)
.unwrap();
const P256_UNCOMPRESSED_BASE: &[u8; 65] = b"\x04\x6b\x17\xd1\xf2\xe1\x2c\x42\x47\xf8\xbc\xe6\xe5\x63\xa4\x40\xf2\x77\x03\x7d\x81\x2d\xeb\x33\xa0\xf4\xa1\x39\x45\xd8\x98\xc2\x96\x4f\xe3\x42\xe2\xfe\x1a\x7f\x9b\x8e\xe7\xeb\x4a\x7c\x0f\x9e\x16\x2b\xce\x33\x57\x6b\x31\x5e\xce\xcb\xb6\x40\x68\x37\xbf\x51\xf5";
const P256_ORDER: asn1::BigUint<'static> = asn1::BigUint::new(b"\x00\xff\xff\xff\xff\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xbc\xe6\xfa\xad\xa7\x17\x9e\x84\xf3\xb9\xca\xc2\xfc\x63\x25\x51").unwrap();

pub const P256_DOMAIN: SpecifiedECDomain<'static> = SpecifiedECDomain {
    version: 1,
    field_id: P256_FIELD,
    curve: Curve {
        a: P256_CURVE_A,
        b: P256_CURVE_B,
        seed: Some(P256_SEED),
    },
    base: P256_UNCOMPRESSED_BASE,
    order: P256_ORDER,
    cofactor: Some(1),
};

pub const P256_DOMAIN_NO_SEED: SpecifiedECDomain<'static> = SpecifiedECDomain {
    version: 1,
    field_id: P256_FIELD,
    curve: Curve {
        a: P256_CURVE_A,
        b: P256_CURVE_B,
        seed: None,
    },
    base: P256_UNCOMPRESSED_BASE,
    order: P256_ORDER,
    cofactor: Some(1),
};

const P384_FIELD: FieldID<'static> = FieldID {
    field_type: asn1::DefinedByMarker::marker(),
    parameters: FieldParameters::PrimeField(asn1::BigUint::new(b"\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff").unwrap()),
};
const P384_CURVE_A: &[u8; 48] = b"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xfc";
const P384_CURVE_B: &[u8; 48] = b"\xb3\x31\x2f\xa7\xe2\x3e\xe7\xe4\x98\x8e\x05\x6b\xe3\xf8\x2d\x19\x18\x1d\x9c\x6e\xfe\x81\x41\x12\x03\x14\x08\x8f\x50\x13\x87\x5a\xc6\x56\x39\x8d\x8a\x2e\xd1\x9d\x2a\x85\xc8\xed\xd3\xec\x2a\xef";
const P384_SEED: asn1::BitString<'static> = asn1::BitString::new(
    b"\xa3\x35\x92\x6a\xa3\x19\xa2\x7a\x1d\x00\x89\x6a\x67\x73\xa4\x82\x7a\xcd\xac\x73",
    0,
)
.unwrap();
const P384_UNCOMPRESSED_BASE: &[u8; 97] = b"\x04\xaa\x87\xca\x22\xbe\x8b\x05\x37\x8e\xb1\xc7\x1e\xf3\x20\xad\x74\x6e\x1d\x3b\x62\x8b\xa7\x9b\x98\x59\xf7\x41\xe0\x82\x54\x2a\x38\x55\x02\xf2\x5d\xbf\x55\x29\x6c\x3a\x54\x5e\x38\x72\x76\x0a\xb7\x36\x17\xde\x4a\x96\x26\x2c\x6f\x5d\x9e\x98\xbf\x92\x92\xdc\x29\xf8\xf4\x1d\xbd\x28\x9a\x14\x7c\xe9\xda\x31\x13\xb5\xf0\xb8\xc0\x0a\x60\xb1\xce\x1d\x7e\x81\x9d\x7a\x43\x1d\x7c\x90\xea\x0e\x5f";
const P384_ORDER: asn1::BigUint<'static> = asn1::BigUint::new(b"\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc7\x63\x4d\x81\xf4\x37\x2d\xdf\x58\x1a\x0d\xb2\x48\xb0\xa7\x7a\xec\xec\x19\x6a\xcc\xc5\x29\x73").unwrap();

pub const P384_DOMAIN: SpecifiedECDomain<'static> = SpecifiedECDomain {
    version: 1,
    field_id: P384_FIELD,
    curve: Curve {
        a: P384_CURVE_A,
        b: P384_CURVE_B,
        seed: Some(P384_SEED),
    },
    base: P384_UNCOMPRESSED_BASE,
    order: P384_ORDER,
    cofactor: Some(1),
};

pub const P384_DOMAIN_NO_SEED: SpecifiedECDomain<'static> = SpecifiedECDomain {
    version: 1,
    field_id: P384_FIELD,
    curve: Curve {
        a: P384_CURVE_A,
        b: P384_CURVE_B,
        seed: None,
    },
    base: P384_UNCOMPRESSED_BASE,
    order: P384_ORDER,
    cofactor: Some(1),
};

const P521_FIELD: FieldID<'static> = FieldID {
    field_type: asn1::DefinedByMarker::marker(),
    parameters: FieldParameters::PrimeField(asn1::BigUint::new(b"\x01\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff").unwrap()),
};
const P521_CURVE_A: &[u8; 66] = b"\x01\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfc";
const P521_CURVE_B: &[u8; 66] = b"\x00\x51\x95\x3e\xb9\x61\x8e\x1c\x9a\x1f\x92\x9a\x21\xa0\xb6\x85\x40\xee\xa2\xda\x72\x5b\x99\xb3\x15\xf3\xb8\xb4\x89\x91\x8e\xf1\x09\xe1\x56\x19\x39\x51\xec\x7e\x93\x7b\x16\x52\xc0\xbd\x3b\xb1\xbf\x07\x35\x73\xdf\x88\x3d\x2c\x34\xf1\xef\x45\x1f\xd4\x6b\x50\x3f\x00";
const P521_SEED: asn1::BitString<'static> = asn1::BitString::new(
    b"\xd0\x9e\x88\x00\x29\x1c\xb8\x53\x96\xcc\x67\x17\x39\x32\x84\xaa\xa0\xda\x64\xba",
    0,
)
.unwrap();
const P521_UNCOMPRESSED_BASE: &[u8; 133] = b"\x04\x00\xc6\x85\x8e\x06\xb7\x04\x04\xe9\xcd\x9e\x3e\xcb\x66\x23\x95\xb4\x42\x9c\x64\x81\x39\x05\x3f\xb5\x21\xf8\x28\xaf\x60\x6b\x4d\x3d\xba\xa1\x4b\x5e\x77\xef\xe7\x59\x28\xfe\x1d\xc1\x27\xa2\xff\xa8\xde\x33\x48\xb3\xc1\x85\x6a\x42\x9b\xf9\x7e\x7e\x31\xc2\xe5\xbd\x66\x01\x18\x39\x29\x6a\x78\x9a\x3b\xc0\x04\x5c\x8a\x5f\xb4\x2c\x7d\x1b\xd9\x98\xf5\x44\x49\x57\x9b\x44\x68\x17\xaf\xbd\x17\x27\x3e\x66\x2c\x97\xee\x72\x99\x5e\xf4\x26\x40\xc5\x50\xb9\x01\x3f\xad\x07\x61\x35\x3c\x70\x86\xa2\x72\xc2\x40\x88\xbe\x94\x76\x9f\xd1\x66\x50";
const P521_ORDER: asn1::BigUint<'static> = asn1::BigUint::new(b"\x01\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x51\x86\x87\x83\xbf\x2f\x96\x6b\x7f\xcc\x01\x48\xf7\x09\xa5\xd0\x3b\xb5\xc9\xb8\x89\x9c\x47\xae\xbb\x6f\xb7\x1e\x91\x38\x64\x09").unwrap();

pub const P521_DOMAIN: SpecifiedECDomain<'static> = SpecifiedECDomain {
    version: 1,
    field_id: P521_FIELD,
    curve: Curve {
        a: P521_CURVE_A,
        b: P521_CURVE_B,
        seed: Some(P521_SEED),
    },
    base: P521_UNCOMPRESSED_BASE,
    order: P521_ORDER,
    cofactor: Some(1),
};

pub const P521_DOMAIN_NO_SEED: SpecifiedECDomain<'static> = SpecifiedECDomain {
    version: 1,
    field_id: P521_FIELD,
    curve: Curve {
        a: P521_CURVE_A,
        b: P521_CURVE_B,
        seed: None,
    },
    base: P521_UNCOMPRESSED_BASE,
    order: P521_ORDER,
    cofactor: Some(1),
};
