Page 1
Java’s Integral Types in PVS
Bart Jacobs
Dep. Comp. Sci., Univ. Nijmegen,
P.O. Box 9010, 6500 GL Nijmegen, The Netherlands.
bart@cs.kun.nl
February 20, 2003
Abstract. This paper extends PVS’s standard bitvector library with multiplica-
tion, division and remainder operations, together with associated results. This ex-
tension isneeded togiveappropriate semanticstoJava’s integral typesin program
verification. Special emphasis is therefore put on Java’s widening and narrowing
functions in relation to the newly defined operations on bitvectors.
1Introduction
Many programmming languages offer different integral types, represented by different
numbers of bits. In Java one has types byte (8 bits), short (16 bits), int (32 bits)
and long (64 bits). Additionally, there is a 16 bit type char for unicode characters,
see [6,
ferences and interpret all of these types as the unbounded, mathematical integers. This
same approach has been followed until recently within the Java verification technol-
ogy developed in Nijmegen around the LOOP translation tool [1] and the PVS theorem
prover [12].
During the last few years the main application area for the LOOP tool is Java Card
based smart cards. Within this setting the abovementioned abstraction of integral types
is problematic, because of the following reasons.
??4.2.1]. It is a usual abstraction in program verification to disregard these dif-
– Given the limited resources on a smart card, a programmerchooses his/her integral
data types as small as possible, so that potential overflows are a concern (see [4,
Chapter14]). Since such overflowsdo not produceexceptions in Java (like in Ada),
a precise semantics is needed.
– Communication between a smart card and a terminal uses a special structured byte
sequence, called an “apdu”, see [4]. As a result, many low-level operations with
bytes occur frequently, such as bitwise negation or masking.
– Unnoticed overflow may form a security risk: imagine you use a short for a se-
quence number in a security protocol, which is incremented with every protocol
run. An overflow then makes you vulnerable to a possible replay attack.
Attention in the theorem proving community has focused mainly on formalising
properties of (IEEE 754) floating-point numbers, see e.g. [2,7,8,14]. Such results are
of interest in the worlds of microprocessor construction and scientific computation.
However, there are legitimate concerns about integral types as well. It is argued in [15]
Page 2
that Java’s integral types are unsafe, because overflow is not detected via exceptions,
and are confusingbecause of the asymmetric way that conversionswork: argumentsare
automatically promoted, but results are not1.
The verification approach centered around the LOOP tool uses the specification
language JML [10,11] in order to express the required correctness properties for Java
programs. Such (simple) properties can also be checked statically with the ESC/Java
tool [5],but such checkingignoresintegralbounds.The theoremproverbased approach
with the semantics of this paper will take bounds into account. In [3] it is proposed that
a specification language like JML for Java) should use the mathematical (unbounded)
integers, for describing the results of programs using bounded integral types, because
“developers are in a different mindset when reading or writing specifications, particu-
larly when it comes to reasoning about integer arithmetic”. This issue is not resolved
yet in the program specification community—and it will not be settled here. Anyway,
Instead, this paper describes the new semantics for Java’s integral types developed
for the LOOP tool. This semantics is based on PVS’s (standard) bitvector library. This
PVS library describes bitvectors of arbitrary length, given as a parameter, togetherwith
functions bv2nat and bv2int for the unsigned (one’s-complement) and signed (two’s-
complement) interpretation of bitvectors. Associated basic operations are defined, such
as addition, subtraction, and concatenation. In this paper, the following items are added
to this library.
1. Executable definitions. For instance, the standard library contains “definitions by
specification” of the form:
-(bv: bvec[N]): { bvn: bvec[N] | bv2int(bvn) =
IF bv2int(bv) = minint THEN bv2int(bv)
ELSE -(bv2int(bv)) ENDIF}
*(bv1: bvec[N], bv2: bvec[N]): {bv: bvec[2*N] | bv2nat(bv) =
bv2nat(bv1) * bv2nat(bv2)}
Such definitions2are not so useful for our program verifications, because some-
times we need to actually compute outcomes. Therefore we give executable redefi-
nitions of these operations. Then we can compute, for instance, (4*b)&0x0F.
2. Similarly, executable definitions are introduced for division and remainder opera-
tions,whicharenotpresentinthestandardlibrary.We give suchdefinitionsbothfor
unsigned and signed interpretations, following standard hardware realisations via
shifting of registers. The associated results are non-trivial challenges in theorem
proving.
3. Typically for Java we introduce so-called widening and narrowing, for turning a
bitvectorof length
? into oneoflength
??? and back,see [6,
??5.1.2and
??5.1.3].
1For a byte (or short) b, the assignment b = b-b leads to a compile time error: the arguments
of the minus function are first converted implicitly to int, but the result must be converted
explicitly back, as in b = (byte)(b-b).
2Readers familiar with PVS will see that these definitions generate so-called type correctness
conditions (TCCs), requiring that the above sets are non-empty. These TCCs can be proved
via the inverses int2bv and nat2bv of the (bijective) functions bv2int and bv2nat, see
Section 2. The inverses exist because one has bijections, but they are not executable.
Page 13
The identity “?????
therestrictionthatoccursin (10).Thestatementaboutthe signoftheremainderis stated
in (13), and about its magnitude in (9).
We conclude that all properties of division and remainder required in the Java Lan-
guage Specification hold for our formalisation in PVS.
????????is equal to
?” in this quoteholds as (11),indeedwithout
7 Conclusions
This paper has formalised the details of multiplication, division and remainder opera-
tions for bitvectors in the higher order logic of the theorem prover PVS, and has made
precise which properties that this formalisation satisfies. This is typical theorem prover
work, involving many subtle details and case distinctions (which humans easily get
wrong). The main application area is Java program verification. Therefore, the rela-
tion between the newly defined bitvectoroperationsand Java’s wideningand narrowing
functions gets much attention.
The theories underlying this paper have recently been included (by Sam Owre) in
the bitvector library of PVS version 3.0 (and upwards). Also, the bitvector semantics is
now heavily used for verifying specific Java programs, see for instance [9].
Acknowledgements
Thanks are due to Joseph Kiniry for his feedback on this paper.
References
1. J. van den Berg and B. Jacobs. The LOOP compiler for Java and JML. In T. Margaria and
W. Yi, editors, Tools and Algorithms for the Construction and Analysis of Systems, number
2031 in Lect. Notes Comp. Sci., pages 299–312. Springer, Berlin, 2001.
2. V.A. Carre˜ no and P.S. Miner. Specification of the IEEE-854 floating-point standard in HOL
and PVS. In E.Th. Schubert, Ph.J. Windley, and J. Alves-Foss, editors, Higher Order Logic
Theorem Proving and Its Applications, 1995. Category B Proceedings, available at URL
http://lal.cs.byu.edu/lal/hol95/Bprocs/indexB.html.
3. P. Chalin. Back to basics: Language support and semantics of basic infinite integer types in
JML and Larch. Techn. rep. CU-CS 2002.003.1
www.cs.concordia.ca/˜faculty/chalin/,2002.
4. Z. Chen. Java Card Technology for Smart Cards. The Java Series. Addison-Wesley, 2000.
5. C. Flanagan, K.R.M. Leino, M. Lillibridge, G. Nelson, J.B. Saxe, and R. Stata. Extended
static checking for Java. In Proceedings of the 2002 ACM SIGPLAN Conference on Pro-
gramming Language Design and Implementation (PLDI), volume 37 of SIGPLAN Notices,
pages 234–245. ACM, 2002.
6. J. Gosling, B. Joy, G. Steele, and G. Bracha. The Java Language Specification Second
Edition. The Java Series. Addison-Wesley, 2000.
http://java.sun.com/docs/books/jls/second_edition/html/
j.title.doc.html.
7. J. Harrison. A machine-checked theory of floating point arithmetic. In Y. Bertot, G. Dowek,
A. Hirschowitz, C. Paulin, and L. Th´ ery, editors, Theorem Proving in Higher Order Logics,
number 1690 in Lect. Notes Comp. Sci., pages 113–130. Springer, Berlin, 1999.
Page 14
8. J. Harrison. Formal verification of IA-64 division algorithms. In M. Aagaard and J. Harrison,
editors, Theorem Proving in Higher Order Logics, number 1869 in Lect. Notes Comp. Sci.,
pages 234–251. Springer, Berlin, 2000.
9. B. Jacobs, M. Oostdijk, and M. Warnier. Formal verification of a secure payment applet.
Journ. of Logic and Algebraic Programming, 2003. To appear.
10. G.T. Leavens, A.L. Baker, and C. Ruby. JML: A notation for detailed design. In H. Kilov
and B. Rumpe, editors, Behavioral Specifications of Business and Systems, pages 175–188.
Kluwer, 1999.
11. G.T. Leavens, E. Poll, C. Clifton, Y. Cheon, and C. Ruby. JML reference manual (draft).
www.jmlspecs.org, 2002.
12. S. Owre, J.M. Rushby, N. Shankar, and F. von Henke. Formal verification for fault-tolerant
architectures: Prolegomena to the design of PVS. IEEE Trans. on Softw. Eng., 21(2):107–
125, 1995.
13. W. Stallings. Computer Organization and Architecture. Prentice Hall,
14. L. Th´ ery. A library for floating-point numbers in Coq.
www-sop.inria.fr/lemme/AOC/coq/,2002.
15. J.F.H. Winkler. A safe variant of the unsafe integer arithmetic of JavaTM. Software—Practice
and Experience, 33:669–701, 2002.
?thedition, 1996.