1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.security.spec;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.math.BigInteger;
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Arrays;
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * An Elliptic Curve with its necessary values.
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class EllipticCurve {
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Underlying finite field
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final ECField field;
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // The first coefficient of the equation defining this elliptic curve
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final BigInteger a;
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // The second coefficient of the equation defining this elliptic curve
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final BigInteger b;
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Bytes used during this elliptic curve generation,
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // if it was generated randomly
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final byte[] seed;
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Hash code
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private volatile int hash;
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new {@code EllipticCurve} with the specified field,
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * coefficients and seed.
47f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param field
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the finite field of this elliptic curve.
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param a
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the coefficient {@code a}.
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param b
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the coefficient {@code b}.
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param seed
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the seed used for the generation of the curve.
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the specified coefficients are not in the specified field.
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public EllipticCurve(ECField field, BigInteger a, BigInteger b, byte[] seed) {
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.field = field;
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.field == null) {
62897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new NullPointerException("field == null");
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.a = a;
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.a == null) {
66897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new NullPointerException("a == null");
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.b = b;
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.b == null) {
70897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new NullPointerException("b == null");
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // make defensive copy
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (seed == null) {
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.seed = null;
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.seed = new byte[seed.length];
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            System.arraycopy(seed, 0, this.seed, 0, this.seed.length);
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // check parameters for ECFieldFp and ECFieldF2m.
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Check invariant: a and b must be in the field.
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Check conditions for custom ECField are not specified.
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.field instanceof ECFieldFp) {
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            BigInteger p = ((ECFieldFp) this.field).getP();
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (this.a.signum() < 0 || this.a.compareTo(p) >= 0) {
85897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new IllegalArgumentException("the a is not in the field");
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (this.b.signum() < 0 || this.b.compareTo(p) >= 0) {
88897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new IllegalArgumentException("the b is not in the field");
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else if (this.field instanceof ECFieldF2m) {
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int fieldSizeInBits = this.field.getFieldSize();
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!(this.a.bitLength() <= fieldSizeInBits)) {
93897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new IllegalArgumentException("the a is not in the field");
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!(this.b.bitLength() <= fieldSizeInBits)) {
96897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new IllegalArgumentException("the b is not in the field");
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new {@code EllipticCurve} with the specified field and
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * coefficients.
104f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param field
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the finite field of this elliptic curve.
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param a
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the coefficient {@code a}.
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param b
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the coefficient {@code b}.
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the specified coefficients are not in the specified field.
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public EllipticCurve(ECField field, BigInteger a, BigInteger b) {
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(field, a, b, null);
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the coefficient {@code a} of this elliptic curve.
120f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the coefficient {@code a} of this elliptic curve.
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigInteger getA() {
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return a;
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the coefficient {@code b} of this elliptic curve.
129f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the coefficient {@code b} of this elliptic curve.
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigInteger getB() {
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return b;
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the finite field of this elliptic curve.
138f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the finite field of this elliptic curve.
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public ECField getField() {
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return field;
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a copy of the seed that was used to generate this elliptic curve.
147f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a copy of the seed that was used to generate this elliptic curve,
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         or {@code null} if none specified.
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte[] getSeed() {
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (seed == null) {
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // return copy
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            byte[] ret = new byte[seed.length];
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            System.arraycopy(seed, 0, ret, 0, ret.length);
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return ret;
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether the specified object equals to this elliptic curve.
164f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param other
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the object to compare.
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the specified object is equal to this elliptic
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         curve, otherwise {@code false}.
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean equals(Object other) {
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this == other) {
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return true;
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!(other instanceof EllipticCurve)) {
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        EllipticCurve otherEc = (EllipticCurve) other;
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return this.field.equals(otherEc.field) && this.a.equals(otherEc.a)
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                && this.b.equals(otherEc.b)
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                && Arrays.equals(this.seed, otherEc.seed);
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the hashcode of this elliptic curve.
185f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the hashcode of this elliptic curve.
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int hashCode() {
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // hash init is delayed
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (hash == 0) {
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int hash0 = 11;
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            hash0 = hash0 * 31 + field.hashCode();
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            hash0 = hash0 * 31 + a.hashCode();
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            hash0 = hash0 * 31 + b.hashCode();
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (seed != null) {
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (int i = 0; i < seed.length; i++) {
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    hash0 = hash0 * 31 + seed[i];
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                hash0 = hash0 * 31;
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            hash = hash0;
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return hash;
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
207