package verifier import ( "crypto/rsa" "math/big" ) var ( // Derived from resources published as: // "ROCA: Vulnerable RSA generation (CVE-2017-15361)". // Czech Republic: Centre for Research on Cryptography and Security, Faculty of Informatics, Masaryk University. fingerprintPrimes = []int64{3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167} fingerprintMasks = []string{ "6", "30", "126", "1026", "5658", "107286", "199410", "8388606", "536870910", "2147483646", "67109890", "2199023255550", "8796093022206", "140737488355326", "5310023542746834", "576460752303423486", "1455791217086302986", "147573952589676412926", "20052041432995567486", "6041388139249378920330", "207530445072488465666", "9671406556917033397649406", "618970019642690137449562110", "79228162521181866724264247298", "2535301200456458802993406410750", "1760368345969468176824550810518", "50079290986288516948354744811034", "473022961816146413042658758988474", "10384593717069655257060992658440190", "144390480366845522447407333004847678774", "2722258935367507707706996859454145691646", "174224571863520493293247799005065324265470", "696898287454081973172991196020261297061886", "713623846352979940529142984724747568191373310", "1800793591454480341970779146165214289059119882", "126304807362733370595828809000324029340048915994", "11692013098647223345629478661730264157247460343806", "187072209578355573530071658587684226515959365500926", } ) // ROCAVulnerableKey returns true if the key is vulnerable to ROCA. func ROCAVulnerableKey(k *rsa.PublicKey) bool { for i := range fingerprintPrimes { n := &big.Int{} n.Mod(k.N, big.NewInt(fingerprintPrimes[i])) n.Lsh(big.NewInt(1), uint(n.Uint64())) mask := &big.Int{} mask.SetString(fingerprintMasks[i], 10) n.And(n, mask) if n.Cmp(big.NewInt(0)) == 0 { return false } } return true }