Magma Script validating the German CSCA self-signed certificate using ECDSA
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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