Skip to content

Instantly share code, notes, and snippets.

@0xLeon
Last active February 10, 2018 10:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 0xLeon/7d4da30cbc90f686e1ebc4264f283456 to your computer and use it in GitHub Desktop.
Save 0xLeon/7d4da30cbc90f686e1ebc4264f283456 to your computer and use it in GitHub Desktop.
Magma Script validating the German CSCA self-signed certificate using ECDSA
// Prime Field Size
p := 0x8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53;
// Curve Parameter One
a := 0x7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826;
// Curve Parameter Two
b := 0x04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11;
// Cofactor
h := 0x01;
// Curve Base Point X
Gx := 0x1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E;
// Curve Base Point Y
Gy := 0x8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315;
// Curve Base Point Order
n := 0x8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565;
// Public Key Point X
Qx := 0x121060DB7E1B47FD7D565812BB71CD155F628ECE000855FC5B33B49EBD9A5D7E76AD209555A24903BF19E5CA96477375;
// Public Key Point Y
Qy := 0x5ED1F02691364E6350F6E4061600C6C4CC3F6744C1148B704F4068C46E94D803C1FCA97AC980708A3324937112E5D243;
// TBSCertificate SHA384 Hash
e_ := 0x6A7E9CEE6DAE7416191FAFD6C2447DEB048735F9596B3B18C76E0C50D6BDD913712888EB0588EDC7AF6552227306574F;
// Signature Value Part One
r_ := 0x4F066B40E3845743DDDFE635BB440865790398038445CC032D527482060C7705BEBAA3D82BA0603C35733FCD2FB32E9D;
// Signature Value Part Two
s_ := 0x8AAB7A13C324E8224CA3A00B81DEBC1928E1FA5C9B09F8A78D162B5A2DDE5A126F00801A87338DFFE08470258106F9CA;
"ECDSA with SHA384 using self-specified Brainpool384 curve";
"";
"Curve domain parameters validation";
if (p mod 2) eq 0 then
error "p is even, which also means it is not prime";
else
"p is odd";
end if;
if IsPrime(p) then
"p is prime";
else
error "p is not prime";
end if;
Mx<x> := PolynomialRing(GF(p));
if a lt 0 or a gt (p - 1) then
error "a is out of range";
else
"a is in range";
end if;
if b lt 0 or b gt (p - 1) then
error "b is out of range";
else
"b is in range";
end if;
if Gx lt 0 or Gx gt (p - 1) then
error "Gx is out of range";
else
"Gx is in range";
end if;
if Gy lt 0 or Gy gt (p - 1) then
error "Gy is out of range";
else
"Gy is in range";
end if;
test := (4 * a^3 + 27 * b^2) mod p;
if test eq 0 then
error "Condition '4a³ + 27b² != 0 mod p' not satisfied";
else
"Condition '4a³ + 27b² != 0 mod p' satisfied";
end if;
E := EllipticCurve(x^3 + a * x + b);
testG1 := (Gy^2) mod p;
testG2 := (Gx^3 + a * Gx + b) mod p;
if testG1 ne testG2 then
error "Generator G is not on curve E";
else
"Generator G is on curve E";
end if;
G := elt<E | Gx, Gy>;
if IsPrime(n) then
"n is prime";
else
error "n is not prime";
end if;
if n gt (2^160) then
"n is greater than 2^160";
else
error "n is not greater than 2^160";
end if;
if n gt (4 * Sqrt(p)) then
"n is greater than 4 * Sqrt(p)";
else
error "n is not greater than 4 * Sqrt(p)";
end if;
if (n * G) eq Id(E) then
"nG is the infinity point";
else
error "nG is not the infinity point";
end if;
h_ := Integers() ! Floor((p + 2 * Sqrt(p) + 1) / n);
if h_ eq h then
"Cofactor matches expected value";
else
error "Cofactor does not match expected value";
end if;
if Order(E) eq p then
error "Anomalous condition not satisfied";
else
"Anomalous condition satisfied";
end if;
t := 1;
B := 100;
movSatisfied := true;
for i := 1 to B do
t := (t * p) mod n;
if t eq 1 then
movSatisfied := false;
break;
end if;
end for;
if movSatisfied then
"MOV condition satisfied";
else
error "MOV condition not satisfied";
end if;
"";
"Public Key Validation";
if Qx lt 0 or Qx gt (p - 1) then
error "Qx is out of range";
else
"Qx is in range";
end if;
if Qy lt 0 or Qy gt (p - 1) then
error "Qy is out of range";
else
"Qy is in range";
end if;
testQ1 := (Qy^2) mod p;
testQ2 := (Qx^3 + a * Qx + b) mod p;
if testQ1 ne testQ2 then
error "Public key Q is not on curve E";
else
"Public key Q is on curve E";
end if;
Q := elt<E | Qx, Qy>;
if Q eq Id(E) then
error "Q is the infinity point";
else
"Q is not the infinity point";
end if;
if (n * Q) eq Id(E) then
"nQ is the infinity point";
else
error "nQ is not the infinity point";
end if;
"";
"Signature validation";
if r_ lt 1 or r_ gt (n - 1) then
error "r' is out of range";
else
"r' is in range";
end if;
if s_ lt 1 or s_ gt (n - 1) then
error "s' is out of range";
else
"s' is in range";
end if;
c := InverseMod(s_, n);
u1 := (e_ * c) mod n;
u2 := (r_ * c) mod n;
P_ := (u1 * G) + (u2 * Q);
if P_ eq Id(E) then
error "Malformed signature";
end if;
x1 := Integers() ! P_[1];
v := x1 mod n;
"";
if r_ eq v then
"VALID SIGNATURE";
else
error "INVALID SIGNATURE";
end if;
# Output certificate to a human readable form
# Prime p, order n, param a, param b extracted via ASN1 output
openssl asn1parse -inform der -i -in csca-germany_103_self_signed.cer > csca-germany_103_self_signed.asn1
# Extract generator G (x, y)
xxd -c 48 -g 48 -s +414 -l 96 -ps -u csca-germany_103_self_signed.cer > Generator.txt
# Extract public key Q (x, y)
xxd -c 48 -g 48 -s +568 -l 96 -ps -u csca-germany_103_self_signed.cer > PubKey.txt
# Extract ECDSA signature (r', s')
openssl asn1parse -inform der -i -in csca-germany_103_self_signed.cer -strparse 1084 > Signature.asn1
# Extract TBSCertificate and get SHA384 hash (e')
openssl asn1parse -inform der -i -in csca-germany_103_self_signed.cer -strparse 4 -noout -out csca-germany_103_self_signed.tbs.der
openssl dgst -sha384 -hex -r csca-germany_103_self_signed.tbs.der > Hash.txt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment