require_relative '../data_conversion' module Ccrypto module Java class ED25519PublicKey < Ccrypto::ED25519PublicKey include DataConversion def to_bin @native_pubKey.encoded end def self.to_key(bin) pubKey = java.security.KeyFactory.getInstance("ED25519", "BC").generatePublic(java.security.spec.X509EncodedKeySpec.new(bin)) ED25519PublicKey.new(pubKey) end def to_pem cont = ["-----BEGIN ED25519 PUBLIC KEY-----\n"] cont << to_b64(to_bin) cont << "\n-----END ED25519 PUBLIC KEY-----" cont.join end def self.from_pem(str) if str =~ /ED25519 PUBLIC/ cont = str.lines[1..-2].join.strip to_key(from_b64(cont)) else raise KeypairEngineException, "Not an ED25519 public key" end end end # ED25519PublicKey class ED25519PrivateKey < Ccrypto::ED25519PrivateKey include DataConversion def self.to_key(bin, &block) if block prov = block.call(:jce_provider) else prov = JCEProvider::BCProv end kf = java.security.KeyFactory.getInstance("ED25519",prov) priv = kf.generate_private(java.security.spec.PKCS8EncodedKeySpec.new(bin)) ED25519PrivateKey.new(priv) end def to_pem cont = ["-----BEGIN ED25519 PRIVATE KEY-----\n"] cont << to_b64(@native_privKey.encoded) cont << "\n-----END ED25519 PRIVATE KEY-----" cont.join end def self.from_pem(str) if str =~ /ED25519 PRIVATE/ cont = str.lines[1..-2].join.strip to_key(from_b64(cont)) else raise KeypairEngineException, "Not an ED25519 private key" end end def to_bin @native_privKey.encoded end def equals?(privKey) if not @native_privKey.nil? case privKey when ED25519PrivateKey @native_privKey.encoded == privKey.to_bin else logger.warn "Unmatched private key : (native) #{@native_privKey} vs. (subject) #{privKey}" false end else logger.warn "ED25519PrivateKey equals? returned false because native_privKey is nil" false end end alias_method :key_equals?, :equals? end # ED25519PrivateKey class ED25519KeyBundle include Ccrypto::ED25519KeyBundle include Ccrypto::X25519KeyBundle include TR::CondUtils include DataConversion include TeLogger::TeLogHelper teLogger_tag :ed25519_kb_j def initialize(kp) @nativeKeypair = kp end def public_key if @pubKey.nil? @pubKey = ED25519PublicKey.new(@nativeKeypair.getPublic) end @pubKey end def private_key ED25519PrivateKey.new(@nativeKeypair.getPrivate) end def derive_dh_shared_secret(pubKey, &block) JCEProvider.instance.add_bc_provider ka = javax.crypto.KeyAgreement.getInstance("X25519",JCEProvider::BCProv.name) ka.init(@nativeKeypair.getPrivate) ka.doPhase(pubKey, true) ka.generateSecret() end end # ED25519KeyBundle class ED25519Engine include TR::CondUtils include DataConversion include TeLogger::TeLogHelper teLogger_tag :ed25519_eng_j def self.supported_params [] end def initialize(*args, &block) @config = args.first end def generate_keypair(&block) JCEProvider.instance.add_bc_provider kg = java.security.KeyPairGenerator.getInstance("ED25519", JCEProvider::BCProv.name) ED25519KeyBundle.new(kg.generateKeyPair) end def sign(val, &block) sign = java.security.Signature.getInstance("EdDSA", JCEProvider::BCProv.name) case @config.keypair when ED25519KeyBundle privKey = @config.keypair.nativeKeypair.getPrivate else raise KeypairEngineException,"Unsupported keypair type '#{@config.keypair.class}'" end sign.initSign(privKey) case val when java.io.InputStream buf = Java::byte[102400].new while((read = val.read(buf, 0, buf.length)) != nil) sign.update(buf,0,read) end else sign.update(to_java_bytes(val)) end sign.sign end def self.verify(pubKey, val, sign) ver = java.security.Signature.getInstance("EdDSA", JCEProvider::BCProv.name) case pubKey when ED25519PublicKey uPubKey = pubKey.native_pubKey else raise KeypairEngineException, "Unsupported public key type '#{pubKey.class}'" end ver.initVerify(uPubKey) case val when java.io.InputStream buf = Java::byte[102400].new while((read = val.read(buf, 0 ,buf.length)) != nil) ver.update(buf,0, read) end else ver.update(to_java_bytes(val)) end ver.verify(to_java_bytes(sign)) end end end end