| package org.mariadb.jdbc.plugin.authentication.standard.ed25519; |
| |
| /** |
| * Basic utilities for EdDSA. Not for external use, not maintained as a public API. |
| * |
| * @author str4d |
| */ |
| public class Utils { |
| |
| /** |
| * Constant-time byte comparison. |
| * |
| * @param b a byte |
| * @param c a byte |
| * @return 1 if b and c are equal, 0 otherwise. |
| */ |
| public static int equal(int b, int c) { |
| int result = 0; |
| int xor = b ^ c; |
| for (int i = 0; i < 8; i++) { |
| result |= xor >> i; |
| } |
| return (result ^ 0x01) & 0x01; |
| } |
| |
| /** |
| * Constant-time byte[] comparison. |
| * |
| * @param b a byte[] |
| * @param c a byte[] |
| * @return 1 if b and c are equal, 0 otherwise. |
| */ |
| public static int equal(byte[] b, byte[] c) { |
| int result = 0; |
| for (int i = 0; i < 32; i++) { |
| result |= b[i] ^ c[i]; |
| } |
| |
| return equal(result, 0); |
| } |
| |
| /** |
| * Constant-time determine if byte is negative. |
| * |
| * @param b the byte to check. |
| * @return 1 if the byte is negative, 0 otherwise. |
| */ |
| public static int negative(int b) { |
| return (b >> 8) & 1; |
| } |
| |
| /** |
| * Get the i'th bit of a byte array. |
| * |
| * @param h the byte array. |
| * @param i the bit index. |
| * @return 0 or 1, the value of the i'th bit in h |
| */ |
| public static int bit(byte[] h, int i) { |
| return (h[i >> 3] >> (i & 7)) & 1; |
| } |
| |
| /** |
| * Converts a hex string to bytes. |
| * |
| * @param s the hex string to be converted. |
| * @return the byte[] |
| */ |
| public static byte[] hexToBytes(String s) { |
| int len = s.length(); |
| byte[] data = new byte[len / 2]; |
| for (int i = 0; i < len; i += 2) { |
| data[i / 2] = |
| (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16)); |
| } |
| return data; |
| } |
| |
| /** |
| * Converts bytes to a hex string. |
| * |
| * @param raw the byte[] to be converted. |
| * @return the hex representation as a string. |
| */ |
| public static String bytesToHex(byte[] raw) { |
| if (raw == null) { |
| return null; |
| } |
| final StringBuilder hex = new StringBuilder(2 * raw.length); |
| for (final byte b : raw) { |
| hex.append(Character.forDigit((b & 0xF0) >> 4, 16)) |
| .append(Character.forDigit((b & 0x0F), 16)); |
| } |
| return hex.toString(); |
| } |
| } |